Python DB-API 2.0规范
PEP:  249
标题: Python Database API Specification v2.0
版本: 83893e13db91
修改日期: 2008-03-03 12:37:19 +0000 (Mon, 03 Mar 2008)
作者: Marc-André Lemburg <mal at lemburg.com>
翻译: 佣工7001
讨论邮件: <db-sig at python.org>
状态: 最终
类别: 信息
创建:  
历史:   
替代: 248
译者注:PEP是Python Enhancement Proposals的缩写,意为Python扩展协议

简介:

定义本API的目的在于鼓励促进所有用于访问数据库的Python模块相互之间的一致性。为了做到这点,我们希望实现一个一致性的指引,以便实现更易于理解的模块,
更加通用的易于在不同数据库间移植的代码,和Python中更广泛的数据库访问手段。
本接口规格由下面几个方面构成:* 模块接口* 数据库连接对象* 游标对象* Type Objects and Constructors* 给模块作者的实现提示* 可选的DB API扩展* 可选的错误处理扩展* 可选的两阶段提交(Two-Phase Commit)扩展* 常见问题* 从版本1.0到2.0的主要变化* 遗留问题(Open Issues)* 脚注(Footnotes)* 鸣谢(Acknowledgments)对于本规范的意见和为题可以去讨论列表the SIG for Database Interfacing with Python(db-sig@python.org)。更多关于Python书库接口的信息可以访问 http://www.python.org/topics/database/.本文档描述了Python DB-API2.0规范和一些常见可选扩展。上一个版本1.0仍然可以在这里PEP 248获得。鼓励程序包的作者们使用上一版的规范来实现,可以作为新版本的基础版本。

模块接口(Module Interface):

    数据库的访问是通过连接对象(connection objects)来实现的。程序模块中必须提供以下形式的连接对象构造函数:connect(parameters...)数据库连接对象的构造函数,返回值为Connection对象实例。 由于目的数据库不同,函数接收数量不等的一些参数。[1]模块中必须定义下面这些模块级的变量:apilevel字符串常量,表明支持的DB API版本。目前只允许取值'1.0'和'2.0'。如果没有定义本常量,默认为DB-API 1.0。threadsafety整数常量,表明模块支持的线程安全级别,可能的值为:0     线程不安全,线程不能共享模块。1     线程可以共享模块,但是不能共享连接对象(connections)。2     线程可以共享模块和连接对象。3     线程安全,线程间可以共享模块、连接对象以及游标对象(module,connections,cursors)。上文中共享的意思是两个线程在没有使用互斥信号(mutex semaphore)锁的情况下, 同时使用一个资源。要注意的是,你并不总能使用互斥信号来确保一个外部资源线程安全,这是因为外部资源很有可能依赖于一个全局变量或是其他的外部资源,然而这些是你不能控制的。paramstyle字符串常量声明模块使用的SQL语句中的参数引出方式。可能的取值如下[2]:'qmark'         问号方式,例如:'...WHERE name=?''numeric'       序数方式,例如:'...WHERE name=:1''named'         命名方式,例如:'...WHERE name=:name''format'        通用方式(ANSI C printf format codes)例如:'...WHERE name=%s''pyformat'      python扩展方式(Python extended format codes),例如:'...WHERE name=%(name)s'模块中应该按照下面所阐述的错误类别和层次关系来处理各种错误信息:Warning 当有严重警告时触发,例如插入数据是被截断等等。必须是Python StandardError的子类(定义于exceptions模块中)。Error 这应该是警告以外所有其他错误类的基类。你可以使用这个类在单一的‘except’语句中捕捉所有的错误。警告(Warnings)不应认为是错误,因此不应该以此类作为基类,而只应该以Python StandardError作为基类。InterfaceError当有数据库接口模块本身的错误(而不是数据库的错误)发生时触发。必须是Error的子类。DatabaseError和数据库有关的错误发生时触发。必须是Error的子类。DataError当有数据处理时的错误发生时触发,例如:除零错误,数据超范围等等。必须是DatabaseError的子类。OperationalError指非用户控制的,而是操作数据库时发生的错误。例如:连接意外断开、数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误。必须是DatabaseError的子类。IntegrityError             完整性相关的错误,例如外键检查失败等。必须是DatabaseError子类。InternalError 数据库的内部错误,例如游标(cursor)失效了、事务同步失败等等。必须是DatabaseError子类。ProgrammingError程序错误,例如数据表(table)没找到或已存在、SQL语句语法错误、参数数量错误等等。必须是DatabaseError的子类。NotSupportedError不支持错误,指使用了数据库不支持的函数或API等。例如在连接对象上使用.rollback()函数,然而数据库并不支持事务或者事务已关闭。必须是DatabaseError的子类。下面是错误类的层次关系:StandardError|__Warning|__Error|__InterfaceError|__DatabaseError|__DataError|__OperationalError|__IntegrityError|__InternalError|__ProgrammingError|__NotSupportedError注:这些例外(Exceptions)的值(错误信息)并没有明确的定义,但是它们应该能够给用户指出足够好的错误提示。

连接对象(Connection Objects):

    连接对象应该具有下面的方法:.close() 马上关闭数据连接(而不是当__del__方法被调用的时候)。连接应该此后变得不可用,再次访问本连接对象应该触发一个错误(Error或其子类),同样所有使用本连接对象的游标(cursor)对象,也会导致例外发生。需要注意的是,在关闭连接对象之前,没有首先提交对数据库的改变将会导致一个隐含的回滚动作(rollback),这将丢弃之前的数据改变操作。.commit()提交任何挂起的事务到数据库中。需要注意的是,如果数据库支持自动提交(auto-commit),必须在初始化时关闭。一般会有一个接口函数关闭此特性。不支持事务的数据库也应该实现此方法,只需什么都不做。.rollback() 由于并非所有数据库都支持事务,此方法是可选的。[3]对于支持事务的数据库,调用此方法将导致数据库回滚到事务开始时的状态。关闭数据库连接之前没有明确调用commit()提交数据更新,将隐含导致rollback()被执行。.cursor()方法返回给定连接上建立的游标对象(Cursor Object)。如果数据库没有提供对应的游标对象,那么将由程序来模拟实现游标功能。[4]

Cursor Objects:

.execute*()    游标对象表示数据库游标,游标用来管理获取结果操作的上下文对象。同一个连接对象创建的游标对象不是彼此隔离的,也就是说一个游标对象对数据库造成的变化将会对于其他游标对象立即可见。而不同的连接对象创建的游标,则可能是隔离的也可能是非隔离的,这取决于数据库对事务的支持的实现(参见连接对象的.rollback()和.commit()方法)。游标对象应具有以下的方法和属性:.description 这是一个只读属性,是7个项目组成的tulip的序列。每个tulip包含描述一个结果集中的列的信息描述:(name, type_code, display_size,internal_size, precision, scale, null_ok)其中,前两个项目(name and type_code)时必须的,其他的五项是可选的。如果没有意义可以设置为None。对于没有返回结果集的操作或者游标对象还没有执行过任何.execute*()的操作本属性可以为空(None)。type_code的含义可以比对下面Type对象的描述。.rowcount 这是一个只读属性,描述的是最后一次数据库操作影响的数据行数(执行.execute系列方法)。 可以是数据查询语句(DQL),比如'select'等返回的数据行,也可以是数据操纵语句(DML )比如'update' 和'insert'语句等所影响的数据行。如果还没有执行过任何语句,或者操作本身影响的函数由于数据访问接口的原因不能检测到。则本属性的值为-1  [7]注:将来的版本有可能重新定义后一种情况,使其取值为空(None)而不是-1。.callproc(procname[,parameters])(由于并非每种数据库都支持存储过程,此方法是可选的 [3])调用数据库存储过程时,首先必须给出存储过程的名字,其次,对于存储过程需要的每一个参数都必须依次给出。调用结果按照调用时的次序,输入型参数(Input parameters)原样不动,输出型和输入输出二合一型参数可能会被新的内容代替。存储过程也很可能以数据结果集作为返回结果,此时就要用标准的fech系列方法来获取结果了(.fetch*() methods)。.close()立即关闭游标(不论 __del__方法是否已调用)。从此刻开始游标对象就变得不可用了。任何试图访问此游标对象的方法或属性的动作都将导致一个错误Error或其子类被抛出。.execute(operation[,parameters]) 准备和执行数据库操作(查询或其他命令)。所提供参数将会被绑定到语句中的变量。变量的定义和数据库模块有关。(请参见模块的paramstyle属性的描述)。[5]游标对象将会保留这个操作的引用,如果一个后续的相同的操作被调用,游标对象将会以此来进行优化。当有相同的操作调用(不同的参数变量被传递)时,这是最为有效的优化。一项数据库操作,为了获得最大的执行效率,最好先期使用方法.setinputsizes() 来指定参数的类型和大小。执行时实际给出的参数和预定义的不同也是合法的,模块的实现需要容忍这个问题,即使以效率的损失为代价。参数可以以tuples的tuple或list的形式提供,例如当在一次调用中插入多行数据。但是这种调用应被认为是抛弃的不建议使用,应该使用专用的方法.executemany() 。没有对返回值进行明确界定。.executemany(operation,seq_of_parameters) 准备数据库操作(查询或其他命令),然后以序列的序列形式的函数来执行该操作。模块开发这可以自由选择是转化为一系列的.execute() 方法调用,还是以数组操作的形式,以便使数据库把这个序列的操作作为一个整体。使用此方法,可能产生一个或多个由未知的行为构成的结果集。建议模块作者(而不是要求)当检测到一次调用已经产生结果集时抛出例外。对于.execute()方法的描述同样可适于此方法。返回值未定义。.fetchone() 从一查询结果集中获取下一行数据,返回值为一个值的序列,如果没有更多数据了则返回None。[6]如果上次的.execute系列方法的调用没有生成任何结果集()或还没有进行任何数据库操作的调用,则调用此方法将抛出例外(Error或其子类)。.fetchmany([size=cursor.arraysize])Fetch the next set of rows of a query result, returning asequence of sequences (e.g. a list of tuples). An emptysequence is returned when no more rows are available.The number of rows to fetch per call is specified by theparameter.  If it is not given, the cursor's arraysizedetermines the number of rows to be fetched. The methodshould try to fetch as many rows as indicated by the sizeparameter. If this is not possible due to the specifiednumber of rows not being available, fewer rows may bereturned.An Error (or subclass) exception is raised if the previouscall to .execute*() did not produce any result set or nocall was issued yet.Note there are performance considerations involved withthe size parameter.  For optimal performance, it isusually best to use the arraysize attribute.  If the sizeparameter is used, then it is best for it to retain thesame value from one .fetchmany() call to the next..fetchall() Fetch all (remaining) rows of a query result, returningthem as a sequence of sequences (e.g. a list of tuples).Note that the cursor's arraysize attribute can affect theperformance of this operation.An Error (or subclass) exception is raised if the previouscall to .execute*() did not produce any result set or nocall was issued yet..nextset() (This method is optional since not all databases supportmultiple result sets. [3])This method will make the cursor skip to the nextavailable set, discarding any remaining rows from thecurrent set.If there are no more sets, the method returnsNone. Otherwise, it returns a true value and subsequentcalls to the fetch methods will return rows from the nextresult set.An Error (or subclass) exception is raised if the previouscall to .execute*() did not produce any result set or nocall was issued yet..arraysizeThis read/write attribute specifies the number of rows tofetch at a time with .fetchmany(). It defaults to 1meaning to fetch a single row at a time.Implementations must observe this value with respect tothe .fetchmany() method, but are free to interact with thedatabase a single row at a time. It may also be used inthe implementation of .executemany()..setinputsizes(sizes)This can be used before a call to .execute*() topredefine memory areas for the operation's parameters.sizes is specified as a sequence -- one item for eachinput parameter.  The item should be a Type Object thatcorresponds to the input that will be used, or it shouldbe an integer specifying the maximum length of a stringparameter.  If the item is None, then no predefined memoryarea will be reserved for that column (this is useful toavoid predefined areas for large inputs).This method would be used before the .execute*() methodis invoked.Implementations are free to have this method do nothingand users are free to not use it..setoutputsize(size[,column])Set a column buffer size for fetches of large columns(e.g. LONGs, BLOBs, etc.).  The column is specified as anindex into the result sequence.  Not specifying the columnwill set the default size for all large columns in thecursor.This method would be used before the .execute*() methodis invoked.Implementations are free to have this method do nothingand users are free to not use it.

数据类型对象及构造(Type Objects and Constructors):

    Many databases need to have the input in a particular format forbinding to an operation's input parameters.  For example, if aninput is destined for a DATE column, then it must be bound to thedatabase in a particular string format.  Similar problems existfor "Row ID" columns or large binary items (e.g. blobs or RAWcolumns).  This presents problems for Python since the parametersto the .execute*() method are untyped.  When the database modulesees a Python string object, it doesn't know if it should be boundas a simple CHAR column, as a raw BINARY item, or as a DATE.To overcome this problem, a module must provide the constructorsdefined below to create objects that can hold special values.When passed to the cursor methods, the module can then detect theproper type of the input parameter and bind it accordingly.A Cursor Object's description attribute returns information abouteach of the result columns of a query.  The type_code must compareequal to one of Type Objects defined below. Type Objects may beequal to more than one type code (e.g. DATETIME could be equal tothe type codes for date, time and timestamp columns; see theImplementation Hints below for details).The module exports the following constructors and singletons:Date(year,month,day)This function constructs an object holding a date value.Time(hour,minute,second)This function constructs an object holding a time value.Timestamp(year,month,day,hour,minute,second)This function constructs an object holding a time stampvalue.DateFromTicks(ticks)This function constructs an object holding a date valuefrom the given ticks value (number of seconds since theepoch; see the documentation of the standard Python timemodule for details).TimeFromTicks(ticks)This function constructs an object holding a time valuefrom the given ticks value (number of seconds since theepoch; see the documentation of the standard Python timemodule for details).TimestampFromTicks(ticks)This function constructs an object holding a time stampvalue from the given ticks value (number of seconds sincethe epoch; see the documentation of the standard Pythontime module for details).Binary(string)This function constructs an object capable of holding abinary (long) string value.STRINGThis type object is used to describe columns in a databasethat are string-based (e.g. CHAR).BINARYThis type object is used to describe (long) binary columnsin a database (e.g. LONG, RAW, BLOBs).NUMBERThis type object is used to describe numeric columns in adatabase.DATETIMEThis type object is used to describe date/time columns ina database.ROWIDThis type object is used to describe the "Row ID" columnin a database.SQL NULL values are represented by the Python None singleton oninput and output.Note: Usage of Unix ticks for database interfacing can causetroubles because of the limited date range they cover.

给模块作者的实现方法示意(Implementation Hints for Module Authors):

    * 时间/日期对象(Date/time objects)可以用Python的datetime模块中的对象来实现(Python 2.3版本开始提供,2.4版本开始提供C版本API),或者使用mxDateTime包中对象(可供Python1.5.2版本以上使用)。它们都提供有足够的构造方法,使用方法(在Python中和C中使用都可以)。* 下面是一个Unix下基于ticks构造为通用的date/time对象的代理示例:
import timedef DateFromTicks(ticks):return Date(*time.localtime(ticks)[:3])def TimeFromTicks(ticks):return Time(*time.localtime(ticks)[3:6])def TimestampFromTicks(ticks):return Timestamp(*time.localtime(ticks)[:6])

* The preferred object type for Binary objects are the buffer types available in standard Python starting with version 1.5.2. Please see the Python documentation for details. For information about the C interface have a look at Include/bufferobject.h and Objects/bufferobject.c in the Python source distribution. * This Python class allows implementing the above type objects even though the description type code field yields multiple values for on type object: class DBAPITypeObject: def __init__(self,*values): self.values = values def __cmp__(self,other): if other in self.values: return 0 if other < self.values: return 1 else: return -1 The resulting type object compares equal to all values passed to the constructor. * Here is a snippet of Python code that implements the exception hierarchy defined above: import exceptions class Error(exceptions.StandardError): pass class Warning(exceptions.StandardError): pass class InterfaceError(Error): pass class DatabaseError(Error): pass class InternalError(DatabaseError): pass class OperationalError(DatabaseError): pass class ProgrammingError(DatabaseError): pass class IntegrityError(DatabaseError): pass class DataError(DatabaseError): pass class NotSupportedError(DatabaseError): pass In C you can use the PyErr_NewException(fullname, base, NULL) API to create the exception objects.

可选的DB API扩展(Optional DB API Extensions):

    在 DB API 2.0生命期内,模块作者经常扩展他们的实现提供超越规范要求的内容,为了增强兼容性和指明清晰的升级到将来DB API版本的道路,本章节定义了一系列的通用对于DB API2.0核心规范内容的扩展。对于所有的DB API可选规范,数据库模块作者可自由选择是否实现这些附加的方法和属性,因此使用它们很有可能导致抛出一个AttributeError或者是NotSupportedError,因为这些方法属性是否支持智能在运行时做检查。因此,已建议在用户使用这些扩展内容时会得到警告消息(Python warnings)为了使这项特性好用,警告消息必须标准化以便可以屏蔽它们。这些标准的信息下面称之为“警告信息”("Warning Message")。Cursor Attribute .rownumberThis read-only attribute should provide the current 0-basedindex of the cursor in the result set or None if the indexcannot be determined.The index can be seen as index of the cursor in a sequence(the result set). The next fetch operation will fetch the rowindexed by .rownumber in that sequence.警告信息(Warning Message): "DB-API extension cursor.rownumber used"Connection Attributes .Error, .ProgrammingError, etc.All exception classes defined by the DB API standard should beexposed on the Connection objects as attributes (in additionto being available at module scope).These attributes simplify error handling in multi-connectionenvironments.
         警告信息(Warning Message): "DB-API extension connection.<exception> used"Cursor Attributes .connectionThis read-only attribute return a reference to the Connectionobject on which the cursor was created.The attribute simplifies writing polymorph code inmulti-connection environments.Warning Message: "DB-API extension cursor.connection used"Cursor Method .scroll(value[,mode='relative'])Scroll the cursor in the result set to a new position accordingto mode.If mode is 'relative' (default), value is taken as offset tothe current position in the result set, if set to 'absolute',value states an absolute target position.An IndexError should be raised in case a scroll operation wouldleave the result set. In this case, the cursor position is leftundefined (ideal would be to not move the cursor at all).Note: This method should use native scrollable cursors, ifavailable , or revert to an emulation for forward-onlyscrollable cursors. The method may raise NotSupportedErrors tosignal that a specific operation is not supported by thedatabase (e.g. backward scrolling).
        警告信息(Warning Message): "DB-API extension cursor.scroll() used"Cursor Attribute .messagesThis is a Python list object to which the interface appendstuples (exception class, exception value) for all messageswhich the interfaces receives from the underlying database forthis cursor.The list is cleared by all standard cursor methods calls (priorto executing the call) except for the .fetch*() callsautomatically to avoid excessive memory usage and can also becleared by executing "del cursor.messages[:]".All error and warning messages generated by the database areplaced into this list, so checking the list allows the user toverify correct operation of the method calls.The aim of this attribute is to eliminate the need for aWarning exception which often causes problems (some warningsreally only have informational character).
        警告信息(Warning Message): "DB-API extension cursor.messages used"Connection Attribute .messagesSame as cursor.messages except that the messages in the listare connection oriented.The list is cleared automatically by all standard connectionmethods calls (prior to executing the call) to avoid excessivememory usage and can also be cleared by executing "delconnection.messages[:]".警告信息(Warning Message):"DB-API extension connection.messages used"Cursor Method .next()Return the next row from the currently executing SQL statementusing the same semantics as .fetchone().  A StopIterationexception is raised when the result set is exhausted for Pythonversions 2.2 and later. Previous versions don't have theStopIteration exception and so the method should raise anIndexError instead.警告信息(Warning Message):"DB-API extension cursor.next() used"Cursor Method .__iter__()Return self to make cursors compatible to the iterationprotocol [8].警告信息(Warning Message):"DB-API extension cursor.__iter__() used"Cursor Attribute .lastrowidThis read-only attribute provides the rowid of the lastmodified row (most databases return a rowid only when a singleINSERT operation is performed). If the operation does not seta rowid or if the database does not support rowids, thisattribute should be set to None.The semantics of .lastrowid are undefined in case the lastexecuted statement modified more than one row, e.g. whenusing INSERT with .executemany().
        警告信息(Warning Message): "DB-API extension cursor.lastrowid used"

可选的错误处理扩展(Optional Error Handling Extensions):

    The core DB API specification only introduces a set of exceptionswhich can be raised to report errors to the user. In some cases,exceptions may be too disruptive for the flow of a program or evenrender execution impossible. For these cases and in order to simplify error handling whendealing with databases, database module authors may choose toimplement user defineable error handlers. This section describes astandard way of defining these error handlers.Cursor/Connection Attribute .errorhandlerRead/write attribute which references an error handler to callin case an error condition is met.The handler must be a Python callable taking the followingarguments:errorhandler(connection, cursor, errorclass, errorvalue) where connection is a reference to the connection on which thecursor operates, cursor a reference to the cursor (or None incase the error does not apply to a cursor), errorclass is anerror class which to instantiate using errorvalue asconstruction argument.The standard error handler should add the error information tothe appropriate .messages attribute (connection.messages orcursor.messages) and raise the exception defined by the givenerrorclass and errorvalue parameters.If no errorhandler is set (the attribute is None), thestandard error handling scheme as outlined above, should beapplied.Warning Message: "DB-API extension .errorhandler used"Cursors should inherit the .errorhandler setting from theirconnection objects at cursor creation time.

可选两阶段提交扩展(Optional Two-Phase Commit Extensions):

    Many databases have support for two-phase commit (TPC) whichallows managing transactions across multiple database connectionsand other resources.If a database backend provides support for two-phase commit andthe database module author wishes to expose this support, thefollowing API should be implemented. NotSupportedError should beraised, if the database backend support for two-phase commitcan only be checked at run-time.TPC Transaction IDsAs many databases follow the XA specification, transaction IDsare formed from three components:* a format ID* a global transaction ID* a branch qualifierFor a particular global transaction, the first two componentsshould be the same for all resources.  Each resource in theglobal transaction should be assigned a different branchqualifier.The various components must satisfy the following criteria:* format ID: a non-negative 32-bit integer.* global transaction ID and branch qualifier: byte strings nolonger than 64 characters.Transaction IDs are created with the .xid() connection method:.xid(format_id, global_transaction_id, branch_qualifier)Returns a transaction ID object suitable for passing to the.tpc_*() methods of this connection.If the database connection does not support TPC, aNotSupportedError is raised.The type of the object returned by .xid() is not defined, butit must provide sequence behaviour, allowing access to thethree components.  A conforming database module could chooseto represent transaction IDs with tuples rather than a customobject.TPC Connection Methods.tpc_begin(xid)Begins a TPC transaction with the given transaction ID xid.This method should be called outside of a transaction(i.e. nothing may have executed since the last .commit() or.rollback()).Furthermore, it is an error to call .commit() or .rollback()within the TPC transaction. A ProgrammingError is raised, ifthe application calls .commit() or .rollback() during anactive TPC transaction.If the database connection does not support TPC, aNotSupportedError is raised..tpc_prepare()Performs the first phase of a transaction started with.tpc_begin().  A ProgrammingError should be raised if thismethod outside of a TPC transaction.After calling .tpc_prepare(), no statements can be executeduntil tpc_commit() or tpc_rollback() have been called..tpc_commit([xid])When called with no arguments, .tpc_commit() commits a TPCtransaction previously prepared with .tpc_prepare().If .tpc_commit() is called prior to .tpc_prepare(), a singlephase commit is performed.  A transaction manager may chooseto do this if only a single resource is participating in theglobal transaction.When called with a transaction ID xid, the database commitsthe given transaction.  If an invalid transaction ID isprovided, a ProgrammingError will be raised.  This form shouldbe called outside of a transaction, and is intended for use inrecovery.On return, the TPC transaction is ended..tpc_rollback([xid])When called with no arguments, .tpc_rollback() rolls back aTPC transaction.  It may be called before or after.tpc_prepare().When called with a transaction ID xid, it rolls back the giventransaction.  If an invalid transaction ID is provided, aProgrammingError is raised.  This form should be calledoutside of a transaction, and is intended for use in recovery.On return, the TPC transaction is ended..tpc_recover()Returns a list of pending transaction IDs suitable for usewith .tpc_commit(xid) or .tpc_rollback(xid).If the database does not support transaction recovery, it mayreturn an empty list or raise NotSupportedError.

常见问题(Frequently Asked Questions):

    在论坛中经常看到关于DB API规范的重复性的问题。本节包括了一些人们常问的问题。Question: 当我使用.fetch*()之类的函数获取结果时,如何获取到一个字典形式的结果集而不是tuples。Answer:有几个可用工具来解决这个问题。多数都是利用了游标对象的.description属性作为基础来实现数据行的字典。注意,之所以没有扩展DB API规范来支持.fetch系列方法来返回字典,是因为这种方法有几个弊端。* 一些数据库及服务不支持区分字段名的大小写,或者自动把字段名转化为大写或小写。* 查询所生成的结果集中的字段不一定是表的字段名,并且数据库经常为这些列使用自己的方法来为这些字段生成名字。因此,要做到在不同的数据库中,都通过使用字典键值来分访问字段值,并且做到可移植的是不可能的。

1.0到2.0的主要改变(Major Changes from Version 1.0 to Version 2.0):

    Python DB API 2.0相对于1.0来说引入了几个很重大的改变。由于其中一些变动会导致已有的基于DB API 1.0的脚本不能运行。因此做了主版本号的改变,升级为DB-API 2.0规范来反映这些变化。下面这些是从1.0 到2.0最重要的改变:* 不在需要单独的dbi模块,而是直接打包进数据库访问模块当中。* 日期/时间类型添加了新的构造,RAW类型改名为BINARY。结果集中应该覆盖现代SQL数据库中的基本数据类型。* 为了更好的数据库绑定,添加了新的常量(apilevel, threadlevel, paramstyle)和方法(.executemany(), .nextset())。* 明确定义了需要用来访问存储过程的的方法.callproc()。* 方法.execute()的返回值定义有所改变。前期版本中,返回值定义是基于所执行的SQL语句类型的(这经常比较难以实现)-- 下载它没有了明确的定义;代替它的是用户应该访问更适合的.rowcount属性。模块作者可以仍然返回旧式的定义值,但是规范中不再会有明确定义,而且应该认为是取决于不同的数据访问模块的。* 例外的类在新的规范中有统一明确的定义。模块作者可以任意的以继承类的形式来扩展新规范中所定义例外的层次。DB API 2.0规范的追加扩展规范:* 定义了附加的可选的对核心DB-API功能的扩展功能集。

遗留问题(Open Issues):

    尽管2.0版本阐明了许多1.0版本遗留的问题 ,但是仍有一些遗留问题留待以后的版本来实现解决:* Define a useful return value for .nextset() for the case wherea new result set is available.* Integrate the decimal module Decimal object for use asloss-less monetary and decimal interchange format.

脚注(Footnotes):

    [1] 作为实现准则,连接对象the connection constructor parameters should beimplemented as keyword parameters for more intuitive use andfollow this order of parameters:dsn         Data source name as stringuser        User name as string (optional)password    Password as string (optional)host        Hostname (optional)database    Database name (optional)E.g. a connect could look like this:connect(dsn='myhost:MYDB',user='guido',password='234$')[2] Module implementors should prefer 'numeric', 'named' or'pyformat' over the other formats because these offer moreclarity and flexibility.[3] If the database does not support the functionality requiredby the method, the interface should throw an exception incase the method is used.The preferred approach is to not implement the method andthus have Python generate an AttributeError incase the method is requested. This allows the programmer tocheck for database capabilities using the standardhasattr() function.For some dynamically configured interfaces it may not beappropriate to require dynamically making the methodavailable. These interfaces should then raise aNotSupportedError to indicate the non-abilityto perform the roll back when the method is invoked.[4] a database interface may choose to support named cursors byallowing a string argument to the method. This feature isnot part of the specification, since it complicatessemantics of the .fetch*() methods.[5] The module will use the __getitem__ method of the parametersobject to map either positions (integers) or names (strings)to parameter values. This allows for both sequences andmappings to be used as input.The term "bound" refers to the process of binding an inputvalue to a database execution buffer. In practical terms,this means that the input value is directly used as a valuein the operation.  The client should not be required to"escape" the value so that it can be used -- the valueshould be equal to the actual database value.[6] Note that the interface may implement row fetching usingarrays and other optimizations. It is notguaranteed that a call to this method will only move theassociated cursor forward by one row.[7] The rowcount attribute may be coded in a way that updatesits value dynamically. This can be useful for databases thatreturn usable rowcount values only after the first call toa .fetch*() method.[8] Implementation Note: Python C extensions will have toimplement the tp_iter slot on the cursor object instead of the.__iter__() method.

鸣谢(Acknowledgements):

    非常感谢Andrew Kuchling,是他把Python Database API Specification 2.0由原始的HTML格式转为了PEP格式。非常感谢James Henstridge领导两阶段提交扩展API的讨论并最终使其标准化。

转载于:https://www.cnblogs.com/dajianshi/archive/2012/04/23/2827096.html

Python DB-API 2.0规范相关推荐

  1. python db api下载_python db api

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  2. python关于row的规范_Python DB-API 2.0规范

    Python DB-API 2.0规范 PEP: 249 标题: Python Database API Specification v2.0 版本: 83893e13db91 作者: Marc-An ...

  3. HTTP API响应数据规范整理

    2019独角兽企业重金招聘Python工程师标准>>> 关于作者 马隆博(Lenbo Ma),Java,Javascript Blog: http://mlongbo.com E-M ...

  4. Python学习22:Python之禅和PEP 8规范

    笔者:风起怨江南 出处:https://blog.csdn.net/JackMengJin 笔者原创,文章转载需注明,如果喜欢请点赞+关注,感谢支持! 导读:Python之禅和PEP 8规范,值得所有 ...

  5. 使用Flask和Connexion构建和记录Python REST API

    If you're writing a web application, then you're probably thinking about making HTTP calls to your s ...

  6. python传递指针_使用Python / C API传递C指针

    我是Python / C API的新手-我正在尝试为我的C程序添加新功能,其中我可以将python嵌入其中并同时扩展功能,以便嵌入式解释器可以执行将与之交互的脚本作为我的C程序的一部分编写的扩展pyt ...

  7. python封装api linux_python Socket编程-python API 与 Linux Socket API之间的关系

    python socket编程 by SA19225409 地址协议家族 Python 支持 AF_UNIX. AF_NETLINK. AF_TIPC 和 AF_INET 家族 AF_UNIX 基于本 ...

  8. python ctypes实现api测试_Python与C之间的相互调用(Python C API及Python ctypes库)

    2010-01-24 17:58 14237人阅读 评论(11) 我实现 Python C API 此部分可以参考我原来的文章< 准备工作: 闲话少说,看看Python C API.事实上,Py ...

  9. python生成api文档_Django 自动生成api接口文档教程

    最近在写测试平台,需要实现一个节点服务器的api,正好在用django,准备使用djangorestframework插件实现. 需求 实现一个接口,在调用时,通过传递的参数,直接运行对应项目的自动化 ...

最新文章

  1. 为什么汉字不能当密码,假如用汉字做密码,又会怎样?
  2. 双节棍「大师」鱼佬亲传武功秘籍:如何进行一场数据挖掘算法竞赛?
  3. 人脸识别的十大过程介绍
  4. 乐乐茶签约帆软软件,打造新式茶饮数字化管理新标杆
  5. 页面导入样式时,使用link和@import有什么区别?
  6. 直击平昌!2天40位大咖的平昌区块链论坛精华都在这了!
  7. AndroidL 开机展示Keyguard锁屏机制初探
  8. 隐私计算头条周刊(10.9-10.15)
  9. 线性反馈移位寄存器(Linear Feedback Shift Register, LFSR)
  10. iis6.0远程代码执行漏洞
  11. wifi协议-802
  12. 被 onnx.checker.check_model 检查出的常见错误
  13. 网站被黑客劫持了选择高防CDN
  14. php判断是否连续出现数字,php通过gbk编码判断 含有连续数字 可用于判断QQ号,手机号等。...
  15. ubuntu 22.04设置字体为Garuda(mac字体Lucida Grande的开源替代)
  16. Win10大更新后(悦米)机械键盘无法使用
  17. hdu 5055(坑)
  18. Tomcat JDBC Pool使用说明
  19. 基于SQLSERVER--数据库表的修复
  20. Java的基本学习(五)——高级UI设计与异常处理

热门文章

  1. iView:一套基于Vue的高质量UI组件库
  2. PHP中memcached的使用
  3. liunx之tar 命令
  4. shell清除日志小脚本
  5. 南洋理工大学科学家研发组装机器人,可以帮助用户组装椅子
  6. android listView嵌套gridview的使用心得
  7. Maven入门(一)(HelloMaven)
  8. 【BZOJ】2675: Bomb
  9. javascript 复习内容
  10. DB2 catalog