Repository navigation
forked from mkleehammer/pyodbc
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
Overview ======== This project is a Python database module for ODBC that implements the Python DB API 2.0 specification. homepage: http://sourceforge.net/projects/pyodbc source: http://github.com/mkleehammer/pyodbc This module requires: * Python 2.4 or greater * ODBC 3.0 or greater On Windows, the easiest way to install is to use the Windows installer program available at http://sourceforge.net/projects/pyodbc. Source can be obtained at To build from source, either check the source out of version control or download a source extract and run: python setup.py build install Module Specific Behavior ======================= General ------- * The pyodbc.connect function accepts a single parameter: the ODBC connection string. This string is not read or modified by pyodbc, so consult the ODBC documentation or your ODBC driver's documentation for details. The general format is: cnxn = pyodbc.connect('DSN=mydsn;UID=userid;PWD=pwd') * Connection caching in the ODBC driver manager is automatically enabled. * Autocommit is not supported. Always call cnxn.commit() since the DB API specification requires a rollback when a connection is closed that was not specifically committed. * When a connection is closed, all cursors created from the connection are closed. Data Types ---------- * Dates, times, and timestamps use the Python datetime module's date, time, and datetime classes. These classes can be passed directly as parameters and will be returned when querying date/time columns. * Binary data is passed and returned in Python buffer objects. * Decimal and numeric columns are passed and returned using the Python 2.4 decimal class. Convenience Methods ------------------- * Cursors are iterable and returns Row objects. cursor.execute("select a,b from tmp") for row in cursor: print row * The DB API PEP does not specify the return type for Cursor.execute, so pyodbc tries to be maximally convenient: 1) If a SELECT is executed, the Cursor itself is returned to allow code like the following: for row in cursor.execute("select a,b from tmp"): print row 2) If an UPDATE, INSERT, or DELETE statement is issued, the number of rows affected is returned: count = cursor.execute("delete from tmp where a in (1,2,3)") 3) Otherwise (CREATE TABLE, etc.), None is returned. * An execute method has been added to the Connection class. It creates a Cursor and returns whatever Cursor.execute returns. This allows for the following: for row in cnxn.execute("select a,b from tmp"): print row or rows = cnxn.execute("select * from tmp where a in (1,2,3)").fetchall() Since each call creates a new Cursor, only use this when executing a single statement. * Both Cursor.execute and Connection.execute allow parameters to be passed as additional parameters following the query. cnxn.execute("select a,b from tmp where a=? or a=?", 1, 2) The specification is not entirely clear, but most other drivers require parameters to be passed in a sequence. To ensure compatibility, pyodbc will also accept this format: cnxn.execute("select a,b from tmp where a=? or a=?", (1, 2)) * Row objects are derived from tuple to match the API specification, but they also support accessing columns by name. for row in cnxn.execute("select A,b from tmp"): print row.a, row.b * The following are not supported or are ignored: nextset, setinputsizes, setoutputsizes. * Values in Row objects can be replaced, either by name or index. Sometimes it is convenient to "preprocess" values. row = cursor.execute("select a,b from tmp").fetchone() row.a = calc(row.a) row[1] = calc(row.b) Goals / Design ============== * This module should not require any 3rd party modules other than ODBC. * Only built-in data types should be used where possible. a) Reduces the number of libraries to learn. b) Reduces the number of modules and libraries to install. c) Eventually a standard is usually introduced. For example, many previous database drivers used the mxDate classes. Now that Python 2.3 has introduced built-in date/time classes, using those modules is more complicated than using the built-ins. * It should adhere to the DB API specification, but be maximally convenient where possible. The most common usages should be optimized for convenience and speed.