PyDBC

GOLDILOCKS PyDBC

Overview

PyDBC programs Python accessing GOLDILOCKS database by using API which complies with Python Database API Specification v2.0(PEP 249).

PyDBC requires the Python standard library, and the internal operation which connects to and operate GOLDILOCKS database requires ODBC library because it calls ODBC API. PyDBC uses gdlcs in ODBC library $GOLDILOCKS_HOME/lib by default, and the user can modify it by updating setup.py.

The internal operation of PyDBC uses ODBC driver, so it is as same as Overview of ODBC Components. There are an architecture of which an application links to the driver manager, and an architecture of which an application links to GOLDILOCKS ODBC driver library.

Version

The information of GOLDILOCKS PyDBC version can be viewed by executing pygoldilocks.so file as follows.

shell>python
>>> import pygoldilocks
>>> print pygoldilocks.version
3.2.0

The current version of GOLDILOCKS PyDBC driver is 3.2.0 according to GOLDILOCKS version, and this driver complies with the standard Python database API 2.0. PyDBC driver supports Python 2.7, 3.4, 3.5, 3.6 versions, and PyDBC driver library should be installed according to each Python version.

Installation

The source should be built to install PyDBC. PyDBC links gdlcs library in GOLDILOCKS_HOME/lib and it includes goldilocks.h header file in GOLDILOCKS_HOME/include, so the environment variable GOLDILOCKS_HOME should be set in an appropriate position.

When installing PyDBC, the bit of Python should be as same as that of GOLDILOCKS library. Therefore, if GOLDILOCKS is built in 32 bit, then PyDBC should be installed by using Python 32 bit.

Installation on Linux

Linux requires the gcc compiler, and it is built as follows.

shell> sudo python setup.py install

It does not support HP-UX nor AIX platform.

Installation on Windows

It is built on Windows as follows.

shell> python setup.py install
An appropriate Microsoft Visual C++ compiler according to python version is required to compile PyDBC
For more information, refer to https://wiki.python.org/moin/WindowsCompilers.

Examples

Obtaining Connection Class

PyDBC implicitly calls ODBC library. Therefore, the data source should be configured to obtain the connection.

import pygoldilocks
cnxn = pygoldilocks.connect( 'DSN=GOLDILOCKS;UID=test;PWD=test' )

Call connect which is an internal function of pygoldilocks, a module of PyDBC, to obtain the connection.

Data Source should be built in advance to use DSN.

If CHARSET is not set in DSN, then ODBC library sets it to Console Character Set. PyDBC implicitly performs the basic encoding for the character set used by ODBC. If the character set used in GOLDILOCKS server is different from that in ODBC library, then the data conversion occurs and it degrades the performance. For example, CP949 is used as a basic character set in Windows. If nothing is set, PyDBC implicitly uses CP949(UHC) when encoding, and ODBC library also uses UHC when processing the character set.

The followings are how to alter the character set of the client.

All of the three methods above alter the connection property of ODBC, SQL_ATTR_CHARACTER_SET, and set the encoding of PyDBC library as well.

Using Cursor and Row Class

A cursor and a row class can be used as follows.

cursor = cnxn.cursor()
cursor.execute( "SELECT NAME, ADDRESS FROM EMP" )

rows = cursor.fetchall()

for row in rows:
    print row.A, row.B

cursor.close()
cnxn.close()

API Reference

pygoldilocks Module

pygoldilocks object complies with Python Database API Specification v2.0.
For more information, refer to Python DB API module.

Properties

connect

It newly connects to the database.

connect( *connectionstring, **kwargs )

It inputs the ODBC connect string and keywords. The keywords are as follows.

Keyword

Description

Default value

attrs_before

It sets properties which should be set before the connection. It receives the value in dictionary type.

-

autocommit

It sets whether to auto commit. If it is false, connection.commit should be called to reflect it in the database.

False

readonly

If it is true, the connection is set to readonly.

False

timeout

It sets the timeout for the connection. SQL_ATTR_LOGIN_TIMEOUT is set.

-

cnxn =  pygoldilocks.connect( "DSN=GOLDILOCKS", attr_before={ pygoldilocks.SQL_ATTR_MAX_ROWS : 1000 })

Date

>>> print pygoldilocks.Date(1984,11,23),  type(pygoldilocks.Date(1984,11,23))
1984-11-23 <type 'datetime.date'>

It creates a date object corresponding to the given value.

Time

>>> print pygoldilocks.Time(11,23,23), type(pygoldilocks.Time(11,23,23))
11:23:23 <type 'datetime.time'>

It creates a time object corresponding to the given value.

Timestamp

>>> print pygoldilocks.Timestamp(1984,11,23,11,23,23), type(pygoldilocks.Timestamp(1984,11,23,11,23,23))
1984-11-23 11:23:23 <type 'datetime.datetime'>

It creates a datetime object corresponding to the given value.

DATETIME

>>> print pygoldilocks.DATETIME(1984,11,23,11,23,23), type(pygoldilocks.DATETIME(1984,11,23,11,23,23))
1984-11-23 11:23:23 <type 'datetime.datetime'>

It creates a datetime object corresponding to the given value. It is as same as Timestamp.

Binary

>>> print pygoldilocks.Binary('binary'), type(pygoldilocks.Binary('binary'))
binary <type 'bytearray'>

It creates a bytearray object corresponding to the given value. It is as same as BINARY.

BINARY

>>> print pygoldilocks.BINARY('binary'), type(pygoldilocks.BINARY('binary'))
binary <type 'bytearray'>

It creates a bytearray object corresponding to the given value.

STRING

>>> print pygoldilocks.STRING('str'), type(pygoldilocks.STRING('str'))
str <type 'str'>

It creates an str object corresponding to the given value.

NUMBER

>>> print pygoldilocks.NUMBER(100.001), type(pygoldilocks.NUMBER(100.001))
100.001 <type 'float'>

It creates a float object corresponding to the given value.

ROWID

>>> print pygoldilocks.ROWID('AA'), type(pygoldilocks.ROWID('AA'))
AA <type 'str'>

It is used to describe the row ID column of the database, and returns an str object.

TimeFromTicks

>>> print pygoldilocks.TimeFromTicks( 10 )
09:00:10

It returns a datetime.time object which is set as an argument value.

DateFromTicks

>>> print pygoldilocks.DateFromTicks( 360000 )
1970-01-05

It returns a datetime.date object which is set as an argument value.

TimestampFromTicks

>>> print pygoldilocks.DateFromTicks( 360000 )
1970-01-05
It returns a datetime.timestamp object which is set as an argument value.

setDecimalSeparator

It sets the decimal point delimiter in NUMERIC type obtained from the database. The default value uses a period (.).

getDecimalSeparator

It obtains the set decimal point delimiter in NUMERIC type.

Connection

It is an object managing the connection with the database, and it is created with connect() function of pygoldilocks module.

Properties

함수

dns_name = cnxn.getinfo( pygoldilocks.SQL_DATA_SOURCE_NAME )
cursor = cnxn.execute( "SELECT COUNT(*) FROM EMP" )

For more information, refer to Cursor.execute() function. This function does not exist in Python API, but it is provided for the convenience. Whenever this function is called, a cursor object is allocated, so it is not recommended to use it when it is required to execute one or more SQL statements.

connection.set_attr( pygoldilocks.SQL_ATTR_TXN_ISOLATION, pygoldilocks.SQL_TXN_SERIALIZABLE )

Cursor

Generally, a cursor object means the database cursor which is used to manage the fetch operation. The database cursor is mapped to ODBC statement handle (HSTMT). The cursor objects which is created by the same connection are not separated. In other words, all updates executed by a cursor to the database are also applied to other cursors.

Cursor does not manage the database transaction, but the connection commits or rolls back the transaction.

Properties

Description

It is the read-only property, and it includes the contents for each column which was returned by SELECT statement executed last with tuple type. Each tuple includes the followings.

  1. Column name (or alias)

  2. Type code

  3. Display size

  4. Internal size

  5. Precision

  6. Scale

  7. Nullable

When SELECT statement is not called, then the description is none.

rowcount

It is the number of rows which were updated by SQL statement which was executed last.

arraysize

It is the number of rows which can be fetched per one time by using fetchmany( [size = cursor.arraysize] ) function. The default value 1.

connection

It is the read-only property, and it indicates the connection object which created the corresponding cursor object.

fast_executemany

If it is set to true, then makes the parameters in array and executes them at once when executing executemany( sql, [*params] ) function. If it is set to false, it separately executes each parameter.

Function

execute( sql, [*params] )

It executes SQL statement through SQLPrepare and SQLExecute functions, then returns a cursor which called this function. 
The parameter option can be used as follows.
cursor.execute( "SELECT A FROM TEST WHERE B=? AND C=?", x, y )
cursor.execute( "SELECT A FROM TEST WHERE B=? AND C=?", (x, y) )

executemany( sql, [*params] )

It executes SQL statement for each parameter and returns none. Parameter params should be a sequence type of a sequence or a sequence generator.

params = [ ( 1, 'A' ), ( 2, 'B' ) ]
cursor.executemany("INSERT INTO TEST( C1, C2 ) VALUES ( ?, ? )", params)
SQL statement is executed twice in the example above. In other words, it is separately executed for  ( 1, 'A' ) and ( 2, 'B') each. The operation of executemany depends on whether fast_executemany of a cursor object is set to true or false.

The example above is as same as follows.

params = [ ( 1, 'A' ), ( 2, 'B' ) ]
for p in params:
    cursor.execute( "INSERT INTO TEST( C1, C2 ) VALUES ( ?, ? )", p )

If fast_executemany is set to true, executemany processes the operation with only a single execute. For that, data in the same index location in items of parameter params should be the same data type.

params = [ ( 1, 'A' ), ( '2', 'B' ) ]
cursor.executemany("INSERT INTO TEST( C1, C2 ) VALUES ( ?, ? )", params)

In the example above, the data type of the first item among two items of parameter params is different. Likewise, the data type on the same index location between items are different, then executemany does not process SQL statement at once, but separately processes it.

If the autocommit of a connection object is true, then SQL statement is processed being splited and each SQL statement is separately committed. If an error occurs while sequentailly processing records, then only some records are committed to the database and the operation is completed leaving some records are not committed. Therefore, it is recommended to set autocommit to false to check if all records are committed to the database when using executemany().

fetchone()

It returns the next row of the query. If the next data does not exist, it is none.

fetchall()

It returns all rows left in the query. Be cautious when using it because it reads all rows to the memory.

fetchmany( [size = cursor.arraysize] )

It returns rows which were left as many as size or cursor.arraysize. The next data returns an empty sequence data. The default value of cursor.arraysize is 1.

commit()

It commits SQL statement. It is a function executed by a connection object which created a cursor object, and it is applied to all cursor which were created in the same connection object. It is as same as commit of the connection object.

rollback()

It rolls back SQL statement. It is a function executed by a connection object which created a cursor object, and it is applied to all cursor which were created in the same connection object. It is as same as rollback of the connection object.

skip( count )

It passes through the record through SQLFetchScroll and SQL_FETCH_NEXT as many times as it is set in count.

nextset()

It returns false because GOLDILOCKS ODBC does not support SQLMoreResults.

close()

It closes a cursor object.

setinputsizes( size_list )

It is an optional function, and receives sequence type as a parameter. It sets INPUT parameter size of SQLBindParameter.

setoutputsize( size )

It is an optional function, and is used for a purpose which is different from that of DB API, and it allocates the buffer size of OUTPUT parameter.

callproc( procname [, params] )

It calls the storage procedure corresponding to procname. The parameter should be a sequence type, and it includes the output parameter. However, data located in the output parameter when inputting is meaningless. callproc function updates data corresponding to INOUT, OUT of the input parameter data, and returns it in sequence type.
create_proc = """CREATE OR REPLACE PROCEDURE PROC1( A1 INTEGER, A2 OUT CHAR(10) )
IS 
  V1 CHAR(10);
BEGIN
  SELECT T1.I1
    INTO V1
    FROM T1
    WHERE T1.I1 >= A1 AND T1.I1 <= A1;
  A2 := V1;
END;\
"""

cursor.execute( create_proc )

result = cursor.callproc( 'PROC1', ( 1, 0 ) )

callfunc( funcname [, params] )

It calls a function corresponding to funcname. callfunc() returns the function data.

create_func = """
CREATE OR REPLACE FUNCTION FUNC1( A1 INTEGER, A2 INTEGER )
  RETURN INTEGER
  IS
    V1 INTEGER;
  BEGIN

    SELECT COUNT(*)
      INTO V1
      FROM T1
      WHERE T1.I1 >= A1 AND T1.I1 <= A2;

    RETURN V1;
  END;\
"""

cursor.execute( create_func )
cursor.commit()

result = cussr.callfunc( 'FUNC1', ( 1,  4) )

tables( table=None, catalog=None, schema=None, tableType=None )

It returns the table information of the database which satisfies the given condition. The character  '_' and '%' are translated as a wild card. Each row has the following column information. For more information, refer to SQLTables.
  1. table_cat: It is the name of the catalog.

  2. table_schem: It is the name of the schema.

  3. table_name: It is the name of the table.

  4. table_type: 'TABLE', 'VIEW', 'SYSTEM TABLE', 'GLOBAL TEMPORARY', 'LOCAL TEMPORARY', 'IMMUTABLE TABLE', 'ALIAS', 'SYNONYM' or a specific type name can be a table type.

  5. remarks: It is a description of a table.

print cursor.tables( table= 'TEST' ).fetchone()

#print table name
for row in cursor.tables():
 print row.table_name

If a parameter is empty, information of all table of which a user has a privilege is returned.

columns( table=None, catalog=None, schema=None, tableType=None )

It obtains the column information of the specified table through SQLColumns function. Each row includes the following column information.

  1. table_cat

  2. table_schem

  3. table_name

  4. column_name

  5. data_type

  6. type_name

  7. column_size

  8. buffer_length

  9. decimal_digits

  10. num_prec_radix

  11. nullable

  12. remarks

  13. column_def

  14. sql_data_type

  15. sql_datetime_sub

  16. char_octet_length

  17. ordinal_position

  18. is_nullable: SQL_NULLABLE, SQL_NO_NULLS or SQL_NULLS_UNKNOWN.

#print column name of table TEST
for r in cursor.columns( table = 'TEST' ):
    print r.column_name

statistics( table, catalog=None, schema=None, unique=False, quick=True )

It obtains the information about the specified table through SQLStatistics function.
If unique is true, it returns an unique index, and if it is false, it returns all indexes.
If quick is true, CARDINALYTIY and PAGES are returned only when it is instantly available, otherwise, NULL is returned to the corresponding column.
  1. table_cat

  2. table_schem

  3. table_name

  4. non_unique

  5. index_qualifier

  6. index_name

  7. type

  8. ordinal_position

  9. column_name

  10. asc_or_desc

  11. cardinality

  12. pages

  13. filter_condition

A wildcard character is not allowed.

rowIdColumns( table, catalog=None, schema=None, nullable=True )

It returns the result set of columns which uniquely identifies a row by executing SQLSpecialColumns with SQL_BEST_ROWID. Each row includes the following column information.

  1. scope: SQL_SCOPE_CURROW, SQL_SCOPE_TRANSACTION, or SQL_SCOPE_SESSION

  2. column_name

  3. data_type: SQL type constant of ODBC

  4. type_name

  5. column_size

  6. buffer_length

  7. decimal_digits

  8. pseudo_column: SQL_PC_UNKNOWN, SQL_PC_NOT_PSEUDO or SQL_PC_PSEUDO

rowVerColumns( table, catalog=None, schema=None, nullable=True )

It returns the result set of columns which are automatically updated when a row is updated by executing SQLSpecialColumns with SQL_ROWVER. Each row includes the following column information.

  1. scope: SQL_SCOPE_CURROW, SQL_SCOPE_TRANSACTION, or SQL_SCOPE_SESSION

  2. column_name

  3. data_type: SQL type constant of ODBC

  4. type_name

  5. column_size

  6. buffer_length

  7. decimal_digits

  8. pseudo_column: SQL_PC_UNKNOWN, SQL_PC_NOT_PSEUDO, or SQL_PC_PSEUDO

primaryKeys( table, catalog=None, schema=None )

It returns the result set of columns which configures major keys of a table by executing SQLPrimaryKeys function. Each row includes the following column information.

  1. table_cat

  2. table_schem

  3. table_name

  4. column_name

  5. key_seq

  6. pk_name

foreignKeys( table=None, catalog=None, schema=None, foreignTable=None, foreignCatalog=None, foreignSchema=None )

It creates the result set of column names of a specified table, or the result set of column names which are foreign keys of another table referring to the basic key of the specified table, by executing SQLForeignKeys function. Each row includes the following column information.

  1. pktable_cat

  2. pktable_schem

  3. pktable_name

  4. pkcolumn_name

  5. fktable_cat

  6. fktable_schem

  7. fktable_name

  8. fkcolumn_name

  9. key_seq

  10. update_rule

  11. delete_rule

  12. fk_name

  13. pk_name

  14. deferrability

procedures( procedure=None, catalog=None, schema=None )

It creates the result set of the information about the procedure by executing SQLProcedures. Each row includes the following column information.

  1. procedure_cat

  2. procedure_schem

  3. procedure_name

  4. num_input_params

  5. num_output_params

  6. num_result_sets

  7. remarks

  8. procedure_type

getTypeInfo( sqlType=None )

It creates the result set of the information about the specified data type or about all data types which are supported by GOLDILOCKS ODBC, by executing SQLGetTypeInfo function. Each row includes the following column information.

  1. type_name

  2. data_type

  3. column_size

  4. literal_prefix

  5. literal_suffix

  6. create_params

  7. nullable

  8. case_sensitive

  9. searchable

  10. unsigned_attribute

  11. fixed_prec_scale

  12. auto_unique_value

  13. local_type_name

  14. minimum_scale

  15. maximum_scale

  16. sql_data_type

  17. sql_datetime_sub

  18. num_prec_radix

  19. interval_precision

Row

A row object is returned with fetch function of a cursor object. It is processed as a tuple type as described in DB API.

row = cursor.fetchone()
for column in row:
    print column

The following features are added to pygoldilocks.

Accessing to a row by using a column name is not only convenient but it also improves the readability. However, if a column name includes Python reserved name or a whitespace, then it be accessed only through row.__getattribute__().

cursor.execute( "select c1 from test")
print cursor.description
row = cursor.fetchone()
print row.C1
(('C1', <type 'str'>, 10, 10, 10, 0, True),)
test

Basically, the identifier of GOLDILOCKS database is uppercase. However, sometimes it is required to be specified in lowercase, so be cautious of using uppercase or lowercase when accessing to a row by using a column name.

Properties

It is the copy of property description of a cursor object which created the corresponding row. For more information, refer to Cursor.description.

Exception

Python exceptions occur by pygoldilocks when GOLDILOCKS ODBC detects an error. The exception classes are as follows, which are as same as Python DB API.

If an error occurs, generally, the exception is processed based on SQLSTATE value provided by the database.

SQLSTATE

Exception

0A000

NotSupportedError

01002

OperationalError

08001

OperationalError

08003

OperationalError

08004

OperationalError

08007

OperationalError

08S01

OperationalError

28000

InterfaceError

40002

IntegrityError

22***

DataError

23***

IntegrityError

24***

ProgrammingError

25***

ProgrammingError

42***

ProgrammingError

Data Type

Transferring Python Parameter to GOLDILOCKS

The data is converted as follows when transferring Python parameter to GOLDILOCKS ODBC.

Python 3

Python datatype

Description

ODBC datatype

None

-

SQL_VARCHAR

str

UTF-8

SQL_VARCHAR or SQL_LONGVARCHAR

bytes, bytearray

binary

SQL_VARBINARY or SQL_LONGVARBINARY

bool

bit

SQL_BIT

datetime.date

date

SQL_TYPE_DATE

datetime.time

time

SQL_TYPE_TIME

datetime.datetime

timestamp

SQL_TYPE_TIMESTAMP

int

integer

SQL_BIGINT

float

floating point

SQL_DOUBLE

decimal

numeric

SQL_NUMERIC

Python 2

Python datatype

Description

ODBC datatype

None


SQL_VARCHAR

str

UTF-8

SQL_VARCHAR or SQL_LONGVARCHAR

bytearray

binary

SQL_VARBINARY or SQL_LONGVARBINARY

buffer

binary

SQL_VARBINARY or SQL_LONGVARBINARY

bool

bit

SQL_BIT

datetime.date

date

SQL_TYPE_DATE

datetime.time

time

SQL_TYPE_TIME

datetime.datetime

timestamp

SQL_TYPE_TIMESTAMP

int

integer

32 bit: SQL_INTEGER, 64 bit: SQL_BIGINT

long

bigint

SQL_BIGINT

float

floating point

SQL_DOUBLE

decimal

numeric

SQL_NUMERIC

SQL Value Received from GOLDILOCKS

The data is converted as follows when transferring the data of GOLDILOCKS database to Python.

Python 3

ODBC datatype

Description

Python datatype

any

NULL

None

SQL_CHAR, SQL_VARCHAR, SQL_LONGVARCHAR

text

text

SQL_BINARY_SQL_VARBINARY, SQL_LONGVARBINARY

binary

bytes

SQL_NUMERIC

decimal, numeric

decimal.Decimal

SQL_BOOLEAN

bit, bool

bool

SQL_SMALLINT, SQL_INTEGER

integers

int

SQL_BIGINT

long

long

SQL_REAL, SQL_FLOAT, SQL_DOUBLE

floating point

float

SQL_TYPE_TIME

time

datetime.time

SQL_TYPE_DATE

date

datetime.date

SQL_TYPE_TIMESTAMP

timestamp

datetime.timestamp

SQL_TYPE_TIME_WITH_TIMEZONE

time with timezone

text

SQL_TYPE_TIMESTAMP_WITH_TIMEZONE

timestamp with timezone

text

SQL_C_INTERVAL_***

interval

text

Python 2

ODBC datatype

Description

Python datatype

any

NULL

None

SQL_CHAR, SQL_VARCHAR, SQL_LONGVARCHAR

text

text

SQL_BINARY_SQL_VARBINARY, SQL_LONGVARBINARY

binary

bytes

SQL_NUMERIC

decimal, numeric

decimal.Decimal

SQL_BOOLEAN

bit, bool

bool

SQL_SMALLINT, SQL_INTEGER

integers

int

SQL_BIGINT

long

long

SQL_REAL, SQL_FLOAT, SQL_DOUBLE

floating point

float

SQL_TYPE_TIME

time

datetime.time

SQL_TYPE_DATE

date

datetime.date

SQL_TYPE_TIMESTAMP

timestamp

datetime.timestamp

SQL_TYPE_TIME_WITH_TIMEZONE

time with timezone

text

SQL_TYPE_TIMESTAMP_WITH_TIMEZONE

timestamp with timezone

text

SQL_C_INTERVAL_***

interval

text

The text of Python data type is converted to unicode in Python 3. It is converted to the unicode or a string according to the character set of the database in Python 2.

Python 2 text

DB character set

Python type

UTF-8

str

SQL_ASCII

str

UHC

unicode

GB18030

unicode