Loading...

Follow MacLochlainns Weblog on Feedspot

Continue with Google
Continue with Facebook
or

Valid
MacLochlainns Weblog by Maclochlainn - 4d ago

Somebody asked why adding a user to the wheel group in didn’t enable them as a sudoer, as qualified in my earlier Fedora post. The reason is that you also need to modify the primary group in the /etc/passwd file to specify the Group ID value for the wheel group as the primary group of the designated student user.

You can identify the Group ID with the following command:

cat /etc/group | grep wheel

It should return the following for the wheel group:

wheel:x:10:student

You need to check the target student user in the /etc/passwd file, which you can do with the following command:

cat /etc/passwd | grep student

It should return the following for the student user, which has a default group value equal to the user of the same name:

student:x:1000:1000:Student:/home/student:/bin/bash

As the root user, edit the /etc/passwd file to correct the student user’s primary group ID, as follows:

student:x:1000:10:Student:/home/student:/bin/bash

You should see the following two lines. If you want authorized sudoers to provide a password (recommended), then modify the first line by removing the # comment. If you don’t want authorized sudoers to provide a password, modify the second line by removing the # comment. Open the /etc/sudoers file with vi or gedit if you’d like a GUI editor.

# %wheel     ALL=(ALL)      ALL
# %wheel     ALL=(ALL)      NOPASSWD: ALL	

Hope this helps. It’s a quick update for Fedora 30, you su to root and add your user to the sudoers list with the following syntax:

usermod someusername -a -G wheel

By the way, don’t forget to log off and then back on to the account.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 3w ago

My students wanted a quick solution on how to find the log files that contain errors. That’s a simple line of code in Linux if you want any Oracle errors that start with ORA-:

find . -type f | xargs grep -i ora\-

It takes only a moment more to look for errors starting with ORA- or PLS-, like:

find . -type f | xargs grep -i -e ora\- -e pls\-

The latter might return something like this:

./contact_lab.txt:PLS-01422
./item_lab.txt:ORA-00001

As always, I hope this helps those looking for a solution.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 1M ago

Sometimes I get poorly thought or just naive questions. That is naive questions because they didn’t read the documentation or don’t understand the semantics of a given programming language. The question this time said they tried to implement what they found on a web page but their sample json_decode function example failed after they followed directions.

Surprise, it didn’t fail because they followed directions. They overlooked part of the example because they didn’t understand how to read a nested array in PHP. The actual example sets up an array of JSON objects, then print_r to read the Array, but the student tried to read it in a foreach loop. Naturally, their sample program raised an error because the base object was an Array not a String, and their target JSON object was nested inside the base Array.

I rewrote the example file to simply convert a JSON structure to an associative array, as follow:


When you call the program, like this

php test.php

It displays

[name][Joe][moniker][Falchetto] 

As always, I hope this helps those looking to display a JSON structure in PHP.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 1M ago

Installing Chrome wasn’t as easy just running the yum utility. You need to download it from the following website.

https://www.google.com/chrome/browser/desktop/index.html

When you try to use the rpm utility to run it, you’ll get the following errors:

warning: google-chrome-stable_current_x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 7fac5991: NOKEY
error: Failed dependencies:
        /usr/bin/lsb_release is needed by google-chrome-stable-74.0.3729.131-1.x86_64
        libappindicator3.so.1()(64bit) is needed by google-chrome-stable-74.0.3729.131-1.x86_64
        liberation-fonts is needed by google-chrome-stable-74.0.3729.131-1.x86_64

The failure points to three missing libraries:

  • lab_release
  • libappindicator3.so.1
  • liberation-fonts

While the error message indicates you’re missing the libappindicator3.so.1 library, the required library is actually the libappindicator-gtk3 library. You can use the yum utility to install the required library from the repository as the root user.

The library you need is actually in the repository as libappindicator-gtk3. You can use the yum utility to install the required library.

yum install -y libappindicator-gtk3
Last metadata expiration check: 1:04:24 ago on Sat 04 May 2019 05:34:34 PM MDT.                                       
Dependencies resolved.                                                                                                
======================================================================================================================
 Package                             Arch                  Version                        Repository             Size 
======================================================================================================================
Installing:                                                                                                           
 libappindicator-gtk3                x86_64                12.10.0-16.fc27                fedora                 41 k 
Installing dependencies:
 libdbusmenu-gtk3                    x86_64                16.04.0-4.fc27                 fedora                 38 k
 libindicator-gtk3                   x86_64                12.10.1-11.fc27                fedora                 67 k

Transaction Summary
======================================================================================================================
Install  3 Packages

Total download size: 147 k
Installed size: 382 k
Downloading Packages:
(1/3): libdbusmenu-gtk3-16.04.0-4.fc27.x86_64.rpm                                      63 kB/s |  38 kB     00:00    
(2/3): libappindicator-gtk3-12.10.0-16.fc27.x86_64.rpm                                 65 kB/s |  41 kB     00:00    
(3/3): libindicator-gtk3-12.10.1-11.fc27.x86_64.rpm                                    93 kB/s |  67 kB     00:00    
----------------------------------------------------------------------------------------------------------------------
Total                                                                                 145 kB/s | 147 kB     00:01     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                              1/1 
  Installing       : libindicator-gtk3-12.10.1-11.fc27.x86_64                                                     1/3 
  Running scriptlet: libindicator-gtk3-12.10.1-11.fc27.x86_64                                                     1/3 
  Installing       : libdbusmenu-gtk3-16.04.0-4.fc27.x86_64                                                       2/3 
  Running scriptlet: libdbusmenu-gtk3-16.04.0-4.fc27.x86_64                                                       2/3 
  Installing       : libappindicator-gtk3-12.10.0-16.fc27.x86_64                                                  3/3 
  Running scriptlet: libappindicator-gtk3-12.10.0-16.fc27.x86_64                                                  3/3 
  Verifying        : libappindicator-gtk3-12.10.0-16.fc27.x86_64                                                  1/3 
  Verifying        : libdbusmenu-gtk3-16.04.0-4.fc27.x86_64                                                       2/3 
  Verifying        : libindicator-gtk3-12.10.1-11.fc27.x86_64                                                     3/3 

Installed:
  libappindicator-gtk3.x86_64 12.10.0-16.fc27                  libdbusmenu-gtk3.x86_64 16.04.0-4.fc27                 
  libindicator-gtk3.x86_64 12.10.1-11.fc27                    

Complete!

While the error message indicates you’re missing the lab_release library, the required library is actually the redhat-lsb-core library. You can use the yum utility to install the required library from the repository as the root user.

yum install -y redhat-lsb-core
Last metadata expiration check: 1:30:39 ago on Sat 04 May 2019 05:34:34 PM MDT.
Dependencies resolved.
======================================================================================================================
 Package                                Arch               Version                          Repository           Size
======================================================================================================================
Installing:
 redhat-lsb-core                        x86_64             4.1-36.fc27                      fedora               42 k
Installing dependencies:
 at                                     x86_64             3.1.20-6.fc27                    fedora               79 k
 mailx                                  x86_64             12.5-25.fc27                     updates             258 k
 ncurses-compat-libs                    x86_64             6.0-14.20170722.fc27             updates             321 k
 redhat-lsb-submod-security             x86_64             4.1-36.fc27                      fedora               20 k
 spax                                   x86_64             1.5.3-10.fc27                    fedora              212 k

Transaction Summary
======================================================================================================================
Install  6 Packages

Total download size: 932 k
Installed size: 1.9 M
Downloading Packages:
(1/6): redhat-lsb-submod-security-4.1-36.fc27.x86_64.rpm                               24 kB/s |  20 kB     00:00    
(2/6): redhat-lsb-core-4.1-36.fc27.x86_64.rpm                                          48 kB/s |  42 kB     00:00    
(3/6): at-3.1.20-6.fc27.x86_64.rpm                                                     80 kB/s |  79 kB     00:00    
(4/6): spax-1.5.3-10.fc27.x86_64.rpm                                                  554 kB/s | 212 kB     00:00    
(5/6): mailx-12.5-25.fc27.x86_64.rpm                                                  1.1 MB/s | 258 kB     00:00    
(6/6): ncurses-compat-libs-6.0-14.20170722.fc27.x86_64.rpm                            903 kB/s | 321 kB     00:00    
----------------------------------------------------------------------------------------------------------------------
Total                                                                                 479 kB/s | 932 kB     00:01     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                              1/1 
  Installing       : mailx-12.5-25.fc27.x86_64                                                                    1/6 
  Installing       : ncurses-compat-libs-6.0-14.20170722.fc27.x86_64                                              2/6 
  Running scriptlet: ncurses-compat-libs-6.0-14.20170722.fc27.x86_64                                              2/6 
  Installing       : spax-1.5.3-10.fc27.x86_64                                                                    3/6 
  Running scriptlet: spax-1.5.3-10.fc27.x86_64                                                                    3/6 
  Installing       : redhat-lsb-submod-security-4.1-36.fc27.x86_64                                                4/6 
  Installing       : at-3.1.20-6.fc27.x86_64                                                                      5/6 
  Running scriptlet: at-3.1.20-6.fc27.x86_64                                                                      5/6 
  Installing       : redhat-lsb-core-4.1-36.fc27.x86_64                                                           6/6 
  Running scriptlet: redhat-lsb-core-4.1-36.fc27.x86_64                                                           6/6 
Running as unit: run-rca25c70a677d4866bb6056b31e1034c3.service
  Verifying        : redhat-lsb-core-4.1-36.fc27.x86_64                                                           1/6 
  Verifying        : at-3.1.20-6.fc27.x86_64                                                                      2/6 
  Verifying        : redhat-lsb-submod-security-4.1-36.fc27.x86_64                                                3/6 
  Verifying        : spax-1.5.3-10.fc27.x86_64                                                                    4/6 
  Verifying        : ncurses-compat-libs-6.0-14.20170722.fc27.x86_64                                              5/6 
  Verifying        : mailx-12.5-25.fc27.x86_64                                                                    6/6 

Installed:
  redhat-lsb-core.x86_64 4.1-36.fc27                       at.x86_64 3.1.20-6.fc27                                   
  mailx.x86_64 12.5-25.fc27                                ncurses-compat-libs.x86_64 6.0-14.20170722.fc27           
  redhat-lsb-submod-security.x86_64 4.1-36.fc27            spax.x86_64 1.5.3-10.fc27                                 

Complete!

The last missing library is liberation-fonts, which you can also install from the repository with the yum utility, like so as the root user:

yum install -y liberation-fonts
Last metadata expiration check: 2:01:27 ago on Sat 04 May 2019 05:34:34 PM MDT.
Dependencies resolved.
======================================================================================================================
 Package                              Arch                Version                          Repository            Size
======================================================================================================================
Installing:
 liberation-fonts                     noarch              1:1.07.4-10.fc27                 updates               17 k
Installing dependencies:
 liberation-narrow-fonts              noarch              1:1.07.4-10.fc27                 updates              208 k

Transaction Summary
======================================================================================================================
Install  2 Packages

Total download size: 225 k
Installed size: 476 k
Downloading Packages:
(1/2): liberation-fonts-1.07.4-10.fc27.noarch.rpm                                      49 kB/s |  17 kB     00:00    
(2/2): liberation-narrow-fonts-1.07.4-10.fc27.noarch.rpm                              336 kB/s | 208 kB     00:00    
----------------------------------------------------------------------------------------------------------------------
Total                                                                                 191 kB/s | 225 kB     00:01     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                              1/1 
  Installing       : liberation-narrow-fonts-1:1.07.4-10.fc27.noarch                                              1/2 
  Installing       : liberation-fonts-1:1.07.4-10.fc27.noarch                                                     2/2 
  Running scriptlet: liberation-fonts-1:1.07.4-10.fc27.noarch                                                     2/2 
  Verifying        : liberation-fonts-1:1.07.4-10.fc27.noarch                                                     1/2 
  Verifying        : liberation-narrow-fonts-1:1.07.4-10.fc27.noarch                                              2/2 

Installed:
  liberation-fonts.noarch 1:1.07.4-10.fc27               liberation-narrow-fonts.noarch 1:1.07.4-10.fc27              

Complete!

You can install the Chrome browser with the following command as the root user:

yum install -y google-chrome-stable_current_x86_64.rpm
Last metadata expiration check: 2:08:09 ago on Sat 04 May 2019 05:34:34 PM MDT.
Dependencies resolved.
======================================================================================================================
 Package                           Arch                Version                        Repository                 Size
======================================================================================================================
Installing:
 google-chrome-stable              x86_64              74.0.3729.131-1                @commandline               56 M

Transaction Summary
======================================================================================================================
Install  1 Package

Total size: 56 M
Installed size: 196 M
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                              1/1 
  Running scriptlet: google-chrome-stable-74.0.3729.131-1.x86_64                                                  1/1 
  Installing       : google-chrome-stable-74.0.3729.131-1.x86_64                                                  1/1 
  Running scriptlet: google-chrome-stable-74.0.3729.131-1.x86_64                                                  1/1 
error: can't create transaction lock on /var/lib/rpm/.rpm.lock (Resource temporarily unavailable)
error: /tmp/google.sig.KSJ5OI: key 1 import failed.
error: can't create transaction lock on /var/lib/rpm/.rpm.lock (Resource temporarily unavailable)
error: /tmp/google.sig.KSJ5OI: key 2 import failed.
Redirecting to /bin/systemctl start atd.service
Running as unit: run-rcb32925ea21c401da74f536a222563ef.service
  Verifying        : google-chrome-stable-74.0.3729.131-1.x86_64                                                  1/1 

Installed:
  google-chrome-stable.x86_64 74.0.3729.131-1                                                                         

Complete!

When you launch the Chrome browser, it will write the following error message to standard out:

[11346:11357:0504/212207.077855:ERROR:ssl_client_socket_impl.cc(946)] handshake failed; returned -1, SSL error code 1, net_error -200
context mismatch in svga_sampler_view_destroy

The issue is corrected in new distributions of Fedora, and shown in the example below:

I hope this helps those looking for a solution.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 2M ago

Started playing around with a native installation of PostgreSQL on my Mac OS X. I navigated to the PostreSQL page to download the program. I downloaded and installed the PostgreSQL Version 11.

Then, I had to connect as the postgres user and start the server. You do that by opening a Terminal, assume the role of superuser root, and then connect as the postgres user. The commands are:

sudo sh
su - postgres
whoami

As the postgres user, you need to set your $PATH environment variable to include the installation of PostgreSQL. You can use the following syntax to add the default directory to the existing $PATH environment:

export PATH=$PATH:/Library/PostgreSQL/11/bin

You can also add the previous line to the postgres user’s .bashrc file, which you’ll need to manually source. You need source the .bashrc file manually because the postgres user can’t connect directly to the server. You must assume the role of the postgres user from the superuser root.

After you have set the environment, you can start the PostgreSQL server with the following command as the postgres user:

pg_ctl -D /Library/PostgreSQL/11/data -l logfile start

Now, you can connect using pgAdmin 4. That’s it for the basic installation. You should see the following after logging in to the PostgeSQL instance:

Basic pgAdmin 4 Consule Screen

As always, I hope this helps those trying to sort out the process.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 3M ago

What happens when your 16 year old doesn’t know he has a hole in his pocket, the iPhone slips down his pant leg unnoticed, and he runs over the device with a snowblower. It’s called instant shredded iPhone. You think that’s bad news but that’s why I purchased AppleCare for the device.

Then, you call Apple and discover that unless they can find and read the IMEI number from a chip, there is no warrantee coverage. That tells me AppleCare is worthless against damage. It’s only of value when you have one of the growing number of iPhone’s with manufacturing defects that you can’t catch within the first year of ownership.

After three calls to Apple, the “senior” technical analyst said you can bring it into the local Apple Store. At that point, I asked, “Did you fail to hear that I live over 250 miles away from the nearest Apple Store?” The analyst said, “Yes, I didn’t hear that.” It was obvious that the situation didn’t fit inside the box that let them close the issue and move on with positive outcome on their staff metrics.

What Apple would like is: The customer pays $99 to replace the phone while they evaluate the pieces to see if they can find an IMEI number. If they can’t find an IMEI number they get to charge full price for the replacement iPhone. They finally agreed to: send a box for me to put the pieces in and mail the pieces to them for evaluation before I agree to pay $99 for a replacement iPhone. That way, I can avoid getting soaked for the retail price when most plans support less expensive upgrade devices.

Ultimately, the likelihood of any value from AppleCare only occurs when you get one of their manufacturing defects, which is increasingly possible.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 4M ago
Microsoft SQL Server provides T-SQL with the ability to assign values from the queries to local variables. While T-SQL returns a SELECT-list, there are rules for how you can assign the SELECT-list values. The process is more or less an all or nothing approach when assigning values to a local variable. The rule is quite simple for scalar variables because the SELECT-list may contain multiple values but assignments must be made one at a time. You can’t mix retrieving values with assignments. Lets say you try to write the following block of T-SQL code:

SELECT 'Execution Scope' AS "Statement";
DECLARE @base NVARCHAR(MAX) = N'';
WITH x AS (SELECT 'Chilly' AS cold, 'Burning up' AS hot)
SELECT @base += cold, hot FROM x;
SELECT @base AS "Result";

You raise the following exception:

Msg 141, Level 15, State 1, Server DESKTOP-4U7EN27, Line 3
A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations.

You should rewrite the query like this:

SELECT 'Execution Scope' AS "Statement";
DECLARE @base NVARCHAR(MAX) = N'';
WITH x AS (SELECT 'Chilly' AS cold, 'Burning up' AS hot)
SELECT @base += cold FROM x;
SELECT @base AS "Result";

While the subquery on line 3 returns a multivalued SELECT-list, the assignment statement appends the value associated with the column name or alias, which acts like a key in a dictionary. While a dictionary is a collection of name and value pairs, you can use the name of any dictionary element as a key to return only one value from the dictionary. That is the value that the name identifies in the dictionary.

You can put a GO on line 6 in an interactive session or you can put the five lines into a T-SQL script file and call it from the sqlcmd utility. You can run the script file with the following syntax, assuming you have a student user with student as its password working against items in the studentdb schema:

sqlcmd -Ustudent -Pstudent -dstudentdb -y40 -itestScope.sql -otestScope.out

Effectively, all T-SQL variables are limited to their execution scope. You determine execution scope interactively by providing the GO command. T-SQL script files are bundles that execute in a single execution scope unless you embed the GO command.

Then, you can display the testScope.out file as follows from the command line (in a cmd session):

type testScope.out

It will display the following:

Statement
---------------
Execution Scope

(1 rows affected)
Result
----------------------------------------
Chilly

(1 rows affected)

As always, I hope this helps those looking for a solution.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 5M ago

You should always have the most current version of pip installed when working with Python. You can upgrade the pip utility with the following command:

sudo pip install --upgrade pip

It should print the following to the console:

Collecting pip
  Downloading https://files.pythonhosted.org/packages/c2/d7/90f34cb0d83a6c5631cf71dfe64cc1054598c843a92b400e55675cc2ac37/pip-18.1-py2.py3-none-any.whl (1.3MB)
    100% |████████████████████████████████| 1.3MB 971kB/s 
Installing collected packages: pip
  Found existing installation: pip 9.0.3
    Uninstalling pip-9.0.3:
      Successfully uninstalled pip-9.0.3
Successfully installed pip-18.1
Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 6M ago

It was a forced upgrade to run TurboTax. The upgrade was simple because I work on a Mac Pro 2012 (with 64 GB of memory and 12 TB of storage. As you can tell from Apple’s support article, you must upgrade the video card.

I bought the SAPPHIRE Radeon PULSE RX 580 8 GB GDDR5 but when I went to install it after upgrading to macOS 10.13 (High Sierra), there was a catch. The original mother board supports a six socket power supply, which Apple failed to mention in their support article. That meant that I had to order a StarTech.com PCI Express 6 pin to 8 pin Power Adapter Cable.

While I still prefer Apple, I don’t appreciate policy of removing devices from their supported parts list. Does Tim really need to sell new Apple devices that badly that he wants to obsolete hardware when the audience can’t support it by disallowing 3rd party vendors from purchasing parts? I know it’s six years old machine but it also isn’t an entry level machine because it costs more than $6,000 with the memory.

Read Full Article
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 
MacLochlainns Weblog by Maclochlainn - 6M ago

While Python is an interpreted language, Python is a very popular programming language. You may ask yourself why it is so popular? The consensus answers to why it’s so popular points to several factors. For example, Python is a robust high-level programming language that lets you:

  • Get complex things done quickly
  • Automate system and data integration tasks
  • Solve complex analytical problems

You find Python developers throughout the enterprise. Development, release engineering, IT operations, and support teams all use Python to solve problems. Business intelligence and data scientists use Python because it’s easy to use.

Developers don’t generally write end-user applications in Python. They mostly use Python as scripting language. Python provides a simple syntax that lets developers get complex things done quickly. Python also provides you with a vast set of libraries that let you can leverage to solve problems. Those libraries often simplify how you analyze complex data or automate repetitive tasks.

This article explains how to use the Python programming language with the Oracle database. It shows you how to install and use the cx_Oracle library to query data. Part 2 will cover how you insert, update, and delete data in the Oracle database, and how you call and use PL/SQL stored functions and procedures.

The article has two parts:

  • How you install and use cx_Oracle with the Oracle database
  • How you query data statically or dynamically

This audience for this article should know the basics of writing a Python program. If you’re completely new to Python, you may want to get a copy of Eric Matthes’ Python Crash Course: A Hands-On, Project-Based Introduction to Programming. More experienced developers with shell scripting backgrounds may prefer Al Sweigart’s Automate the Boring Stuff with Python.

This article uses Python 2.7, which appears to be the primary commercial version of Python in most organizations. At least, it’s what most vendors ship with Linux distros. It also happens to be the Python distro on Fedora Linux.

How you install and use cx_Oracle with the Oracle database

The first step requires that you test the current version of Python on your Operating System (OS). For the purpose of this paper, you use the student user account. The student user is in the sudoer list, which gives the account super user privileges.

You can find the Python version by opening a Terminal session and running the following command:

[student@localhost ~]$ python -V

It displays:

Python 2.7.5

You can download the current version of the cx_Oracle library at the Python Software Foundation’s web site. At the time of writing, the current version of the cx_Oracle is the cx_Oracle 5.2.1 version. The cx_Oracle library is available for download as a Red Hat Package Manager (RPM) module.

You download the cx_Oracle-5.2.1-11g-py26-1.x86_64.rpm to the /tmp directory or to a sudoer-enabled user’s downloads directory. Let’s assume you download the RPM into the /tmp directory. After you download the RPM, you can install it with the yum utility with this syntax:

yum install -y /tmp/cx_Oracle-5.2.1-11g-py27-1.x86_64.rpm

The cx_Oracle library depends on the Oracle Client software, which may or may not be installed. It installs without a problem but would raise a runtime error when using the Python software. You can check whether cx_Oracle is installed with the following syntax:

rpm –qa oracle-instantclient11.2-basic

If the oracle-instantclient11.2-basic library isn’t installed, the command returns nothing. If the oracle-instantclient11.2-basic library is installed it returns the following:

oracle-instantclient11.2-basic-11.2.0.4.0-1.x86_64

Assuming you don’t have the Oracle Client software installed, you should download it from Oracle’s Instant Client Downloads web page. After you download the RPM, you install the Oracle 11g Release 2 Client software with the following syntax:

yum install -y /tmp/oracle-instantclient11.2-basic-11.2.0.4.0-1.x86_64.rpm

You now have the necessary software installed and configured to run and test Python programs that work with the Oracle database. Python uses a standard path configuration to look for Python modules or libraries. You can see that set of path values by connecting to the Python IDLE environment, which is the runtime environment. The IDLE environment is very much like the SQL*Plus environment.

You connect to the Python IDLE environment by typing the following:

python

It opens the Python IDLE environment. It should display the following:

Python 2.7.5 (default, Apr 10 2015, 08:09:05) 
[GCC 4.8.3 20140911 (Red Hat 4.8.3-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

You import the sys library and then you can print the path elements with the following command:

>>> import sys
>>> print sys.path

It should print the following for Python 2.7 in Fedora Linux:

['', '/usr/lib64/python27.zip', '/usr/lib64/python2.7', '/usr/lib64/python2.7/plat-linux2', '/usr/lib64/python2.7/lib-tk', '/usr/lib64/python2.7/lib-old', '/usr/lib64/python2.7/lib-dynload', '/usr/lib64/python2.7/site-packages', '/usr/lib64/python2.7/site-packages/gtk-2.0', '/usr/lib/python2.7/site-packages']

You can now test whether the environment works by typing the following commands in the IDLE environment:

>>> import cx_Oracle
>>> db = cx_Oracle.connect("student/student@xe")
>>> print db.version

It prints:

11.2.0.2.0

The other two sections require you to test components inside Python files. That means you need to supplement the default Python path variable. You do that by adding values to the Python environment variable, which is $PYTHONPATH.

The following adds the /home/student/Code/python directory to the Python path variable:

export set PYTHONPATH=/home/student/Code/python

Next, we create an connection.py file, which holds the following:

# Import the Oracle library.
import cx_Oracle
 
try:
  # Create a connection.
  db = cx_Oracle.connect("student/student@xe")
 
  # Print a message.
  print "Connected to the Oracle " + db.version + " database."

except cx_Oracle.DatabaseError, e:
  error, = e.args
  print >> sys.stderr, "Oracle-Error-Code:", error.code
  print >> sys.stderr, "Oracle-Error-Message:", error.message
 
finally
  # Close connection. 
  db.close()

The import statement adds the cx_Oracle library to the program scope. The cx_Oracle library’s connect function takes either the user name and password, or the user name, password, and TNS alias.

The except block differs from what you typically see. The code value maps to the SQLCODE value and the message value maps to the SQLERRM value.

You can test the connection.py file as follows in the /home/student/Code/python directory:

python connection.py

It prints the following:

Connected to the Oracle 11.2.0.2.0 database.

This section has shown you how to setup the cx_Oracle library, and how you can test the cx_Oracle library with Python programs.

How you query data statically or dynamically

The prior section shows you how to connect to an Oracle instance and how to verify the driver version of the cx_Oracle library. Like most ODBC and JDBC software, Python first creates a connection. Then, you need to create a cursor inside a connection.

The basicCursor.py program creates a connection and a cursor. The cursor holds a static SQL SELECT statement. The SELECT statement queries a string literal from the pseudo dual table.

# Import the Oracle library.
import sys
import cx_Oracle
 
try:
  # Create a connection.
  db = cx_Oracle.connect("student/student@xe")
 
  # Create a cursor.
  cursor = db.cursor()
 
  # Execute a query.
  cursor.execute("SELECT 'Hello world!' FROM dual")
 
  # Read the contents of the cursor.
  for row in cursor:
    print (row[0]) 
 
except cx_Oracle.DatabaseError, e:
  error, = e.args
  print >> sys.stderr, "Oracle-Error-Code:", error.code
  print >> sys.stderr, "Oracle-Error-Message:", error.message
 
finally:
  # Close cursor and connection. 
  cursor.close()
}  db.close()

The connect function assigns a database connection to the local db variable. The cursor function returns a cursor and assigns it to the local cursor variable. The execute function dispatches the query to Oracle’s SQL*Plus and returns the result set into a row element of the local cursor variable. The for-each loop reads the row element from the cursor variable and prints one row at a time. Since the cursor only returns a string literal, there’s only one row to return.

You test the program with this syntax:

python basicConnection.py

It prints:

Hello world!

The next basicTable.py program queries the item table. The item table holds a number of rows of data. The code returns each row inside a set of parentheses.

# Import the Oracle library.
import cx_Oracle

try:
  # Create a connection.
  db = cx_Oracle.connect("student/student@xe")

  # Create a cursor.
  cursor = db.cursor()

  # Execute a query.
  cursor.execute("SELECT item_title " +
                 ",      item_rating " +
                 "FROM   item " +
                 "WHERE  item_type = "
                 "        (SELECT common_lookup_id " +
                 "         FROM   common_lookup " +
                 "         WHERE  common_lookup_type = 'DVD_WIDE_SCREEN')")

  # Read the contents of the cursor.
  for row in cursor:
    print (row[0], row[1]) 
 
except cx_Oracle.DatabaseError, e:
  error, = e.args
  print >> sys.stderr, "Oracle-Error-Code:", error.code
  print >> sys.stderr, "Oracle-Error-Message:", error.message
 
finally:
  # Close cursor and connection. 
  cursor.close()
  db.close()

The SQL query is split across several lines by using the + operator. The + operator concatenates strings, and it lets you format a long query statement. The range for loop returns tuples from the cursor. The tuples are determined by the SELECT-list of the query.

The query returns the following type of results:

('Casino Royale', 'PG-13')
...
('Star Wars - Episode I', 'PG')
('Star Wars - Episode II', 'PG')
('Star Wars - Episode III', 'PG-13')
('Star Wars - Episode IV', 'PG')
('Star Wars - Episode V', 'PG')
('Star Wars - Episode VI', 'PG')

At this point, you know how to work with static queries. The next example shows you how to work with dynamic queries. The difference between a static and dynamic query is that an element of the string changes.

You have two options for creating dynamic strings. The first lets you glue a string inside a query. The second lets you embed one or more bind variables in a string. As a rule, you should use bind variables because they avoid SQL injection risks.

The following is the basicDynamicTable.py script

# Import the Oracle library.
import cx_Oracle

sRate = 'PG-13'

try:
  # Create a connection.
  db = cx_Oracle.connect("student/student@xe")

  # Define a dynamic statment.
  stmt = "SELECT item_title, item_rating FROM item WHERE item_rating = :rating"

  # Create a cursor.
  cursor = db.cursor()

  # Execute a statement with a bind variable.
  cursor.execute(stmt, rating = sRate)

  # Read the contents of the cursor.
  for row in cursor:
    print (row[0], row[1]) 
 
except cx_Oracle.DatabaseError, e:
  error, = e.args
  print >> sys.stderr, "Oracle-Error-Code:", error.code
  print >> sys.stderr, "Oracle-Error-Message:", error.message
 
finally:
  # Close cursor and connection. 
  cursor.close()
  db.close()

You need to assign a dynamic SQL statement to a local string variable. The bind variable is preceded with a colon (:). The execute function takes a string variable with the dynamic SQL statement. Then, you provide a name and value pair. The name needs to match the bind variable in the dynamic SQL statement. The value needs to map to a local Python variable.

The query should return a full list from the item table for the two item_title and item_rating columns:

('Casino Royale', 'PG-13')
...
('Harry Potter and the Goblet of Fire', 'PG-13')
('Harry Potter and the Order of the Phoenix', 'PG-13')
('The Lord of the Rings - Fellowship of the Ring', 'PG-13')
('The Lord of the Rings - Two Towers', 'PG-13')
('The Lord of the Rings - The Return of the King', 'PG-13')
('The Lord of the Rings - The Return of the King', 'PG-13')

This article should have shown you how to effectively work static and dynamic queries. You can find the scripts on the github.com server.

Read Full Article

Read for later

Articles marked as Favorite are saved for later viewing.
close
  • Show original
  • .
  • Share
  • .
  • Favorite
  • .
  • Email
  • .
  • Add Tags 

Separate tags by commas
To access this feature, please upgrade your account.
Start your free month
Free Preview