Python @ DjangoSpin

50+ Know-How(s) Every Pythonista Must Know

Buffer this pageShare on FacebookPrint this pageTweet about this on TwitterShare on Google+Share on LinkedInShare on StumbleUpon
Reading Time: 21 minutes

Page #5


Connecting to Oracle databases with Python

Python has a third party library called cx_Oracle, which helps you to work with Oracle databases. You can install it with pip or download it from The Cheese Shop. Expand the following snippet to view working examples of a few basic operations like:

  • connecting to a database
  • executing DDL (Data Definition Language) statements like CREATE, ALTER
  • executing DML (Data Manipulation Language) statements like INSERT, UPDATE, DELETE
  • executing DQL (Data Query Language) statement i.e. SELECT
############################### CONNECTING TO A DATABASE ######################
The connect() method of the cx_Oracle module takes a connection string which contain the database credentials in the format: user/password@host/instance. The method returns a Connection object if it succeeds in connecting. In my experience, it takes 10-15 seconds to connect.

>>> import cx_Oracle
>>> oracleConnection = cx_Oracle.connect('user/password@host/instance')






################### EXECUTING DDL (DATA DEFINITION LANGUAGE) STATEMENT: CREATE, ALTER #################
Before executing any statements, you will have to obtain a Cursor object by calling the cursor() method of the Connection object. Once you have done that, you can use the execute() method of the Cursor object to execute statements. Be sure to close the cursor when you are done by calling cursor.close().
>>> import cx_Oracle
>>> oracleConnection = cx_Oracle.connect('user/password@host/instance')

#### DDL: CREATE ####
>>> oracleCursor = oracleConnection.cursor()
>>> oracleCursor.execute('''CREATE TABLE EMPLOYEE
    (EMP_ID INT PRIMARY KEY NOT NULL,
    FIRST_NAME VARCHAR2(50) NOT NULL,
    LAST_NAME VARCHAR2(50) NOT NULL)''')
	
#### DDL: ALTER ####
>>> oracleCursor.execute('ALTER TABLE EMPLOYEE ADD DOB DATE')
>>> oracleCursor.execute('ALTER TABLE EMPLOYEE DROP COLUMN DOB')

>>> oracleCursor.close()

# Do NOT put a semi-colon at the end of the statementS (e.g. NOT NULL);'''), because if you do, then Python raises cx_Oracle.DatabaseError.</p>






################ EXECUTING DML (DATA MANIPULATION LANGUAGE) STATEMENTS: INSERT, UPDATE, DELETE ###############
>>> import cx_Oracle
>>> oracleConnection = cx_Oracle.connect('user/password@host/instance')

>>> oracleCursor = oracleConnection.cursor()
>>> oracleCursor.execute('''CREATE TABLE EMPLOYEE
    (EMP_ID INT PRIMARY KEY NOT NULL,
    FIRST_NAME VARCHAR2(50) NOT NULL,
    LAST_NAME VARCHAR2(50) NOT NULL)''')
	
#### DML: INSERT ####
>>> oracleCursor.execute('''INSERT INTO EMPLOYEE
    (EMP_ID, FIRST_NAME, LAST_NAME)
    VALUES(1, 'Ethan', 'Hunt')''')
>>> oracleCursor.execute('COMMIT')

#### DML: UPDATE ####
>>> oracleCursor.execute('''UPDATE EMPLOYEE
	SET EMP_ID=7
    WHERE FIRST_NAME = 'Ethan'
    ''')
>>> oracleCursor.execute('COMMIT')

#### DML: DELETE ####
>>> oracleCursor.execute('COMMIT')
>>> oracleCursor.execute('''DELETE FROM EMPLOYEE
    WHERE EMP_ID = 7''')
>>> oracleCursor.execute('COMMIT')

>>> oracleCursor.close()






######### EXECUTING DQL (DATA QUERY LANGUAGE) STATEMENT: SELECT ###########

>>> import cx_Oracle
>>> oracleConnection = cx_Oracle.connect('user/password@host/instance')

>>> oracleCursor = oracleConnection.cursor()
>>> oracleCursor.execute('''CREATE TABLE EMPLOYEE
    (EMP_ID INT PRIMARY KEY NOT NULL,
    FIRST_NAME VARCHAR2(50) NOT NULL,
    LAST_NAME VARCHAR2(50) NOT NULL)''')
	
>>> oracleCursor.execute('''INSERT INTO EMPLOYEE
    (EMP_ID, FIRST_NAME, LAST_NAME)
    VALUES(1, 'Ethan', 'Hunt')''')
>>> oracleCursor.execute('''INSERT INTO EMPLOYEE
    (EMP_ID, FIRST_NAME, LAST_NAME)
    VALUES(2, 'Tyrion', 'Lannister')''')
>>> oracleCursor.execute('COMMIT')


#### DQL: SELECT ####
>>> resultSet = oracleCursor.execute('SELECT * FROM EMPLOYEE')
>>> for record in resultSet:
	print(record)

(1, 'Ethan', 'Hunt')
(2, 'Tyrion', 'Lannister')


>>> oracleCursor.close()

Using the embedded SQLite database with Python

Python ships a module called sqlite3 which enables you to work with a builtin database called SQLite3 without having to install its client application. SQLite3 is compliant with DB-API 2.0 specification with an SQL interface.

The following snippet briefly explains how to connect to an existing database, create a new database in the current directory and execute different types of statements.

>>> import sqlite3

# Use the connect() function to connect to an existing database (a .db file) in the current directory. If the specified file doesn’t exist, it will create a new file in the current directory. This method returns a Connection object which we can use later to execute DDL, DML and other types of statements.
>>> sqlite3Connection = sqlite3.connect('myTest.db')




# The execute() function of the Connection object allows us to execute statements.
## DDL: Data Definition Language: CREATE ##
>>> sqlite3Connection.execute('''CREATE TABLE EMPLOYEE
    (EMP_ID INT PRIMARY KEY NOT NULL,
    FIRST_NAME VARCHAR(50) NOT NULL,
    LAST_NAME VARCHAR(50) NOT NULL);''')
<sqlite3.Cursor object at 0x0368C1A0>
 
 
## DDL: Data Definition Language: ALTER ##
>>> sqlite3Connection.execute('ALTER TABLE EMPLOYEE ADD COLUMN DOB DATE;')
<sqlite3.Cursor object at 0x039051A0>

## DML: Data Manipulation Language: INSERT ##
>>> sqlite3Connection.execute('''INSERT INTO EMPLOYEE
    (EMP_ID, FIRST_NAME, LAST_NAME)
    VALUES(1, 'Ethan', 'Hunt');''')
<sqlite3.Cursor object at 0x039051A0>
 
 
## DML: Data Manipulation Language: UPDATE ##
>>> sqlite3Connection.execute('''UPDATE EMPLOYEE
    SET EMP_ID=1
    WHERE FIRST_NAME = 'Ethan';''')
<sqlite3.Cursor object at 0x03D26D20>
 
 
## DML: Data Manipulation Language: DELETE ##
>>> sqlite3Connection.execute('''DELETE FROM EMPLOYEE
    WHERE EMP_ID = 1;''')
<sqlite3.Cursor object at 0x03D26D60>

## DQL: Data Query Language SELECT ##
>>> cursor = sqlite3Connection.execute("SELECT *  from EMPLOYEE")
>>> for record in cursor:
    print(record)
 
(7, 'Ethan', 'Hunt')

Creating Secure Hashes/Message Digests using hashlib module

The builtin hashlib module provides an interface to create secure hashes/message digests of algorithms such as SHA1, SHA224, SHA256, SHA384, and SHA512 & RSA’s MD5. Each of these algorithms has a corresponding class in the module, the constructors of which, along with its hexdigest() methods produces secure hashes/message digests. The input is in bytes form and output is in hexadecimal digits.

>>> import hashlib 

# sha1 hash 
>>> hashlib.sha1(b"DjangoSpin: Articles for Pythonistas").hexdigest() 
'8fe8bdf0a83213d9d5ff43a5d3f3d951994e18e3'

# sha256 hash 
>>> hashlib.sha256(b"DjangoSpin: Articles for Pythonistas").hexdigest()  	
'ea6f0fc02c4fac9f95cf0e03a18004b87c212c473eaa4bb3e1882255f0bbbdbf' 

# MD5 hash 
>>> hashlib.md5(b"DjangoSpin: Articles for Pythonistas").hexdigest() 
'59af3c14b3f913f37e18a096bad723c2'

Using the __init__() magic method

The __init__ method is one of several class methods which are called implicitly on certain events. These methods are called magic methods, or dunder methods, because of the double underscore in front of the method name. These methods need not be defined, but if defined, Python will execute them on certain events. The __init__() method is called when an instance is created.

The init stands for initialization, as it initializes attributes of the instance. It is called the constructor of a class.

# initializing an instance with static data
>>> class Man:
	def __init__(self):
		self.name = 'Ethan'
		self.age = 10
		self.weight = 60
		self.height = 100
	def details(self):
		print("Hi, I am {}. I am {} years old. I weigh {} lbs and I am {} cm tall.".
			format(self.name, self.age, self.weight, self.height))

		
>>> ethan = Man()
>>> ethan.details()
Hi, I am Ethan. I am 10 years old. I weigh 60 lbs and I am 100 cm tall.


# initializing an instance with dynamic data
>>> class Man:
	def __init__(self, name, age, weight, height):
		self.name = name
		self.age = age
		self.weight = weight
		self.height = height
	def details(self):
		print("Hi, I am {}. I am {} years old. I weigh {} lbs and I am {} cm tall.".
				format(self.name, self.age, self.weight, self.height))

		
>>> ethan = Man('Ethan', 10, 60, 100)
>>> ethan.details()
Hi, I am Ethan. I am 10 years old. I weigh 60 lbs and I am 100 cm tall.

Using the __str__() magic method

Like the __init__() method, the __str__() method is one of several class methods which are called implicitly on certain events. These methods are called magic methods, or dunder methods, because of the double underscore in front of the method name. These methods need not be defined, but if defined, Python will execute them on certain events. The __str__ magic method is called when the object is printed, for example, while printing it. The __str__ is defined to return a string representation of the instance.

# When the __str__() is not defined
>>> class Man:
	def __init__(self, name, age, weight, height):
		self.name = name
		self.age = age
		self.weight = weight
		self.height = height
		print("1.", self)

		
>>> ethan = Man('Ethan', 10, 60, 100)
1. <__main__.Man object at 0x033D0710>		# from print(self)
>>> print(ethan)
<__main__.Man object at 0x033D0710>			# from print(instanceName)
>>> 
>>> 
>>> 
>>> 
>>> 
# When the __str__() is defined
>>> class Man:
	def __init__(self, name, age, weight, height):
		self.name = name
		self.age = age
		self.weight = weight
		self.height = height
		print("1.", self)
	def __str__(self):
		return "{} | {} | {} | {}".format(self.name, self.age, self.weight, self.height)

	
>>> ethan = Man('Ethan', 10, 60, 100)
1. Ethan | 10 | 60 | 100					# from print(self)
>>> print(ethan)
Ethan | 10 | 60 | 100						# from print(instanceName)

Getting size of an object in memory

The getsizeof() function of sys module tells us about the size of an object in memory in bytes. This can be particularly useful while identifying performance bottlenecks.

>>> import sys
>>> sys.getsizeof(5)
14
>>> sys.getsizeof('hello')
30
>>> sys.getsizeof( [1, 2, 3, 4] )
52

Using builtin function globals()

The builtin globals() function returns a dictionary containing objects accessible anywhere in the program.

>>> help(globals)
Help on built-in function globals in module builtins:

globals(...)
    globals() -> dictionary
    
    Return the dictionary containing the current scope's global variables.

### EXAMPLES ###
>>> aGlobalVariable = 'accessible everywhere.'
>>> print(globals())
{'__builtins__': <module 'builtins' (built-in)>, '__spec__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, 'aGlobalVariable': 'accessible everywhere.', '__name__': '__main__', '__doc__': None}
>>> def aConfinedPieceOfCode():
	aLocalVariable = 'accessible only locally.'
	print(globals())
	
>>> aConfinedPieceOfCode()
{'__builtins__': <module 'builtins' (built-in)>, '__spec__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, 'aConfinedPieceOfCode': <function aConfinedPieceOfCode at 0x03159A08>, 'aGlobalVariable': 'accessible everywhere.', '__name__': '__main__', '__doc__': None}

>>> 'aGlobalVariable' in globals()
True

Using builtin function locals()

The builtin locals() function returns a dictionary containing objects accessible only in the current scope.

>>> help(locals)
Help on built-in function locals in module builtins:

locals(...)
    locals() -> dictionary
    
    Update and return a dictionary containing the current scope's local variables.

	
### EXAMPLES ###
>>> aLocalVariable = 'accessible only locally.'
>>> print(locals())														# locals() of module
{'__builtins__': <module 'builtins' (built-in)>, '__spec__': None, '__package__': None, '__doc__': None, 'aLocalVariable': 'accessible only locally.', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__name__': '__main__'}

>>> def aConfinedPieceOfCode():
	anotherLocalVariable = 'accessible only locally; present inside a function.'
	
	print("Printing dictionary of local objects:", locals())			# locals() of this scope.
	
	if 'anotherLocalVariable' in locals():
		print("Present.")

		
>>> aConfinedPieceOfCode()
Printing dictionary of local objects: {'anotherLocalVariable': 'accessible only locally; present inside a function.'}
Present.

Bear in mind that any top-level code in the module(i.e. code at the first indent level) goes in the local namespace of the module, constituting the global namespace.


Using builtin function vars()

The builtin function vars(obj) returns the dictionary of the attributes belonging to an instance/object as returned by the __dict__ attribute of the object. When used without an argument, it returns the the dictionary of local objects.

>>> help(vars)
Help on built-in function vars in module builtins:

vars(...)
    vars([object]) -> dictionary
    
    Without arguments, equivalent to locals().
    With an argument, equivalent to object.__dict__.

### EXAMPLES ###
>>> class Ethan():
	def __init__(self):
		self.name = 'Ethan'
		self.age = 23

>>> ethan = Ethan()

# Equivalent to object.__dict__ when called by passing an object.
>>> vars(ethan)
{'age': 23, 'name': 'Ethan'}
>>> ethan.__dict__
{'age': 23, 'name': 'Ethan'}

>>> 'age' in vars(ethan)
True

# Equivalent to locals() when called without arguments.
>>> vars()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, 'Ethan': <class '__main__.Ethan'>, '__spec__': None, '__package__': None, '__builtins__': <module 'builtins' (built-in)>, '__name__': '__main__', '__doc__': None, 'ethan': <__main__.Ethan object at 0x03090810>}

Reloading a module

There are occasions when you have changed the code of a module, and you want the changes to reflect without having to relaunch the interpreter or restart the server. Python doesn't support this by default. However, the reload() function of importlib standard library helps you to do just that.

# CONTENTS OF foo.py
def spam():
    print("SPAM!")

# A SESSION IN THE INTERACTIVE INTERPRETER
>>> import foo
>>> foo.spam()
SPAM!

# CHANGED CONTENTS OF foo.py
def spam():
    print("SPAM! SPAM!")

# SAME SESSION IN THE INTERACTIVE INTERPRETER
>>> foo.spam()						
SPAM!										# Changes have not reflected yet.
>>> import importlib
>>> importlib.reload(foo)
<module 'foo' from 'complete_path_to_foo.py'>
>>> foo.spam()
SPAM! SPAM!



#### Common Practice to Handle Frequently Modified Modules ####
import moduleOne
import moduleTwo
from importlib import reload

reload(moduleOne)
reload(moduleTwo)

from moduleOne import *
from moduleTwo import *

See also: 50+ Tips & Tricks for Python Developers


Buffer this pageShare on FacebookPrint this pageTweet about this on TwitterShare on Google+Share on LinkedInShare on StumbleUpon

Leave a Reply