PEP 249 – Python 数据库 API 规范 v2.0
- 作者:
- Marc-André Lemburg <mal at lemburg.com>
- 讨论列表:
- Db-SIG 列表
- 状态:
- 最终版
- 类型:
- 信息性
- 创建时间:
- 1999 年 4 月 12 日
- 历史记录:
- 替换:
- 248
简介
定义此 API 的目的是鼓励使用 Python 访问数据库的模块之间的相似性。通过这样做,我们希望实现一致性,从而使模块更容易理解,代码在数据库之间更便携,并扩展 Python 对数据库连接的覆盖范围。
有关此规范的意见和问题可以发送到 Python 数据库接口 SIG。
有关使用 Python 进行数据库接口和可用软件包的更多信息,请参阅 数据库主题指南。
本文档描述了 Python 数据库 API 规范 2.0 和一组常见的可选扩展。之前的版本 1.0 版本仍然可用作参考,在 PEP 248 中。鼓励软件包编写者使用此规范版本作为新接口的基础。
模块接口
构造函数
可以通过连接对象访问数据库。模块必须提供以下构造函数来创建这些对象
全局变量
必须定义以下模块全局变量
- apilevel
- 字符串常量,表示支持的 DB API 级别。
目前只允许字符串“
1.0
”和“2.0
”。如果没有给出,则应假定 DB-API 1.0 级接口。
- threadsafety
- 整数常量,表示接口支持的线程安全级别。可能的值是
threadsafety 含义 0 线程不能共享模块。 1 线程可以共享模块,但不能共享连接。 2 线程可以共享模块和连接。 3 线程可以共享模块、连接和游标。 在上述情况下共享意味着两个线程可以使用一个资源,而无需使用互斥信号量来包装它以实现资源锁定。请注意,您不能总是通过使用互斥量来管理访问来使外部资源线程安全:该资源可能依赖于超出您控制范围的全局变量或其他外部来源。
- paramstyle
- 字符串常量,表示接口期望的参数标记格式类型。可能的值是 [2]
paramstyle 含义 qmark
问号风格,例如 ...WHERE name=?
numeric
数字位置风格,例如 ...WHERE name=:1
named
命名风格,例如 ...WHERE name=:name
format
ANSI C printf 格式代码,例如 ...WHERE name=%s
pyformat
Python 扩展格式代码,例如 ...WHERE name=%(name)s
异常
该模块应该通过这些异常或它们的子类来提供所有错误信息
- Warning
- 针对重要警告(如插入时数据截断等)引发的异常。它必须是 Python
Exception
类的子类 [10] [11]。
- Error
- 所有其他错误异常的基类异常。您可以使用它用一个
except
语句捕获所有错误。警告不被视为错误,因此不应使用此类作为基类。它必须是 PythonException
类的子类 [10]。
- InterfaceError
- 针对与数据库接口而不是数据库本身相关的错误引发的异常。它必须是 Error 的子类。
- DatabaseError
- 针对与数据库相关的错误引发的异常。它必须是 Error 的子类。
- DataError
- 针对由于处理数据的问题(如除以零、数值超出范围等)引发的错误引发的异常。它必须是 DatabaseError 的子类。
- OperationalError
- 针对与数据库操作相关的错误引发的异常,这些错误不一定在程序员的控制之下,例如意外断开连接、找不到数据源名称、无法处理事务、处理期间发生内存分配错误等。它必须是 DatabaseError 的子类。
- IntegrityError
- 当数据库的关系完整性受到影响时引发的异常,例如外键检查失败。它必须是 DatabaseError 的子类。
- InternalError
- 当数据库遇到内部错误时引发的异常,例如游标不再有效、事务不同步等。它必须是 DatabaseError 的子类。
- ProgrammingError
- 针对编程错误引发的异常,例如表未找到或已存在、SQL 语句语法错误、指定的参数数量错误等。它必须是 DatabaseError 的子类。
- NotSupportedError
- 如果使用的方法或数据库 API 不受数据库支持,则会引发此异常,例如,在不支持事务或已关闭事务的连接上请求 .rollback()。它必须是 DatabaseError 的子类。
Exception
|__Warning
|__Error
|__InterfaceError
|__DatabaseError
|__DataError
|__OperationalError
|__IntegrityError
|__InternalError
|__ProgrammingError
|__NotSupportedError
注意
这些异常的值未定义。不过,它们应该让用户对出错的原因有一个相当好的了解。
连接对象
连接对象应该响应以下方法。
连接方法
- .close()
- 立即关闭连接(而不是在调用
.__del__()
时关闭)。从此时起,连接将不可用;如果尝试使用连接执行任何操作,将引发 Error(或其子类)异常。这同样适用于尝试使用连接的所有游标对象。请注意,在未先提交更改的情况下关闭连接会导致执行隐式回滚。
- .commit()
- 将任何挂起的交易提交到数据库。
请注意,如果数据库支持自动提交功能,则该功能最初必须关闭。可以提供一个接口方法来重新打开它。
不支持事务的数据库模块应该使用空功能实现此方法。
- .rollback()
- 此方法是可选的,因为并非所有数据库都提供事务支持。 [3]
如果数据库提供事务,则此方法会导致数据库回滚到任何挂起事务的开始。在未先提交更改的情况下关闭连接会导致执行隐式回滚。
- .cursor()
- 使用连接返回一个新的 游标 对象。
如果数据库没有提供直接的游标概念,则模块必须使用其他方式来模拟游标,以满足此规范的要求。 [4]
游标对象
这些对象表示数据库游标,它用于管理提取操作的上下文。从同一个连接创建的游标不是隔离的,即,一个游标对数据库所做的任何更改都会立即被其他游标看到。从不同连接创建的游标可以或不可以被隔离,具体取决于事务支持是如何实现的(另请参阅连接的 .rollback() 和 .commit() 方法)。
游标对象应该响应以下方法和属性。
游标属性
- .description
- 此只读属性是一个包含 7 个项序列的序列。
每个序列都包含描述一个结果列的信息
name
type_code
display_size
internal_size
precision
scale
null_ok
前两个项目 (
name
和type_code
) 是必需的,其他五个项目是可选的,如果无法提供有意义的值,则设置为None
。对于不返回行或游标尚未通过 .execute*() 方法调用操作的操作,此属性将为
None
。可以通过将
type_code
与下面部分中指定的 类型对象 进行比较来解释它。
- .rowcount
- 此只读属性指定最后一次 .execute*() 生成的行数(对于像
SELECT
这样的 DQL 语句)或影响的行数(对于像UPDATE
或INSERT
这样的 DML 语句)。 [9]如果游标尚未执行 .execute*() 或最后一次操作的行数无法通过接口确定,则该属性为 -1。 [7]
注意
DB API 规范的未来版本可能会重新定义后一种情况,使对象返回
None
而不是 -1。
游标方法
- .callproc( procname [, parameters ] )
- (此方法是可选的,因为并非所有数据库都提供存储过程。 [3])
调用具有给定名称的存储数据库过程。参数序列必须包含过程期望的每个参数的一个条目。调用的结果将作为输入序列的修改副本返回。输入参数保持不变,输出参数和输入/输出参数被可能的新值替换。
过程也可以提供结果集作为输出。然后必须通过标准的 .fetch*() 方法使其可用。
- .close()
- 立即关闭游标(而不是在
__del__
被调用时关闭)。从此时起,游标将不可用;如果尝试对游标进行任何操作,将引发 Error(或子类)异常。
- .execute(operation [, parameters])
- 准备并执行数据库操作(查询或命令)。
参数可以作为序列或映射提供,并将绑定到操作中的变量。变量在特定于数据库的符号中指定(有关详细信息,请参阅模块的 paramstyle 属性)。 [5]
游标将保留对操作的引用。如果再次传递相同的操作对象,则游标可以优化其行为。对于使用相同操作但将不同的参数绑定到它(多次)的算法,这最有效。
为了在重用操作时获得最大效率,最好使用 .setinputsizes() 方法提前指定参数类型和大小。参数不匹配预定义信息是合法的;实现应该进行补偿,可能以效率降低为代价。
参数也可以指定为元组列表,例如在单个操作中插入多行,但这种用法已弃用:应该使用 .executemany()。
返回值未定义。
- .executemany( operation, seq_of_parameters )
- 准备一个数据库操作(查询或命令),然后针对在序列 seq_of_parameters 中找到的所有参数序列或映射执行它。
模块可以自由地使用对 .execute() 方法的多次调用来实现此方法,或者使用数组操作让数据库在一个调用中整体处理序列。
对于产生一个或多个结果集的操作,使用此方法构成了未定义的行为,并且允许(但不要求)实现当检测到操作调用创建了结果集时引发异常。
与 .execute() 相同的注释也相应地适用于此方法。
返回值未定义。
- .fetchone()
- 获取查询结果集的下一行,返回单个序列,或者当没有更多数据可用时返回
None
。 [6]如果对 .execute*() 的先前调用没有产生任何结果集或尚未发出任何调用,则会引发 Error(或子类)异常。
- .fetchmany([size=cursor.arraysize])
- 获取查询结果的下一组行,返回一个序列的序列(例如,元组列表)。当没有更多行可用时,将返回一个空序列。
每次调用的获取行数由参数指定。如果未给出,则游标的 arraysize 确定要获取的行数。该方法应尝试获取与大小参数指示的尽可能多的行。如果由于指定行数不可用而无法做到这一点,则可能返回更少的行。
如果对 .execute*() 的先前调用没有产生任何结果集或尚未发出任何调用,则会引发 Error(或子类)异常。
请注意,size 参数涉及性能考虑。为了获得最佳性能,通常最好使用 .arraysize 属性。如果使用大小参数,则最好使其从一个 .fetchmany() 调用到下一个调用保持相同的值。
- .fetchall()
- 获取查询结果的所有(剩余)行,并将它们作为序列的序列(例如,元组列表)返回。请注意,游标的 arraysize 属性会影响此操作的性能。
如果对 .execute*() 的先前调用没有产生任何结果集或尚未发出任何调用,则会引发 Error(或子类)异常。
- .nextset()
- (此方法是可选的,因为并非所有数据库都支持多个结果集。 [3])
此方法将使游标跳到下一个可用集,丢弃当前集中任何剩余的行。
如果没有更多集,该方法将返回
None
。否则,它将返回一个真值,并且随后对 .fetch*() 方法的调用将从下一个结果集返回行。如果对 .execute*() 的先前调用没有产生任何结果集或尚未发出任何调用,则会引发 Error(或子类)异常。
- .arraysize
- 此读写属性指定使用 .fetchmany() 每次获取的行数。它默认为 1,表示每次获取一行。
实现必须在 .fetchmany() 方法方面遵守此值,但可以自由地每次一行与数据库进行交互。它也可以在 .executemany() 的实现中使用。
- .setinputsizes(sizes)
- 这可以在调用 .execute*() 之前使用,以预定义操作参数的内存区域。
sizes 作为序列指定 - 每个输入参数一个项目。该项目应是与将要使用的输入相对应的类型对象,或者它应是指定字符串参数最大长度的整数。如果该项目为
None
,则不会为该列预留任何预定义内存区域(这对避免为大型输入预留预定义区域很有用)。此方法将在调用 .execute*() 方法之前使用。
实现可以自由地让此方法不做任何事情,用户也可以自由地不使用它。
- .setoutputsize(size [, column])
- 为大型列(例如
LONG
、BLOB
等)的获取设置列缓冲区大小。列指定为结果序列中的索引。不指定列将为游标中所有大型列设置默认大小。此方法将在调用 .execute*() 方法之前使用。
实现可以自由地让此方法不做任何事情,用户也可以自由地不使用它。
类型对象和构造函数
许多数据库需要将输入以特定格式绑定到操作的输入参数。例如,如果输入是针对 DATE
列,则必须以特定字符串格式绑定到数据库。类似的问题存在于“行 ID”列或大型二进制项(例如 blob 或 RAW
列)中。这给 Python 带来问题,因为 .execute*() 方法的参数是无类型的。当数据库模块看到一个 Python 字符串对象时,它不知道它应该将其绑定为一个简单的 CHAR
列,作为原始 BINARY
项目,还是作为 DATE
。
为了克服这个问题,模块必须提供下面定义的构造函数来创建可以保存特殊值的 对象。当传递给游标方法时,模块随后可以检测输入参数的正确类型并相应地绑定它。
Cursor 对象的 description 属性返回有关查询的每个结果列的信息。 type_code
必须与下面定义的类型对象之一相等。类型对象可能等于多个类型代码(例如,DATETIME
可能等于日期、时间和时间戳列的类型代码;有关详细信息,请参阅下面的 实现提示)。
该模块导出以下构造函数和单例
- Date(year, month, day)
- 此函数构造一个保存日期值的 对象。
- Time(hour, minute, second)
- 此函数构造一个保存时间的 对象。
- Timestamp(year, month, day, hour, minute, second)
- 此函数构造一个保存时间戳值的 对象。
- DateFromTicks(ticks)
- 此函数从给定的滴答值(自纪元以来的秒数;有关详细信息,请参阅 标准 Python 时间模块 的文档)构造一个保存日期值的 对象。
- TimeFromTicks(ticks)
- 此函数从给定的滴答值(自纪元以来的秒数;有关详细信息,请参阅标准 Python 时间模块的文档)构造一个保存时间的 对象。
- TimestampFromTicks(ticks)
- 此函数从给定的滴答值(自纪元以来的秒数;有关详细信息,请参阅标准 Python 时间模块的文档)构造一个保存时间戳值的 对象。
- Binary(string)
- 此函数构造一个能够保存二进制(长)字符串值的 对象。
- STRING 类型
- 此类型对象用于描述数据库中基于字符串的列(例如
CHAR
)。
- BINARY 类型
- 此类型对象用于描述数据库中(长)二进制列(例如
LONG
、RAW
、BLOB
)。
- NUMBER 类型
- 此类型对象用于描述数据库中的数字列。
- DATETIME 类型
- 此类型对象用于描述数据库中的日期/时间列。
- ROWID 类型
- 此类型对象用于描述数据库中的“行 ID”列。
SQL NULL
值在输入和输出中由 Python None
单例表示。
注意
使用 Unix 滴答进行数据库接口可能会因为它们覆盖的日期范围有限而造成麻烦。
可选的 DB API 扩展
在 DB API 2.0 的生命周期中,模块作者经常将其实现扩展到 DB API 规范要求的范围之外。为了增强兼容性并为未来版本的规范提供清晰的升级路径,本节定义了一组对核心 DB API 2.0 规范的常见扩展。
与所有 DB API 可选功能一样,数据库模块作者可以自由地不实现这些额外的属性和方法(使用它们会导致 AttributeError
),或者在只有在运行时才能检查可用性时,抛出 NotSupportedError。
有人建议通过 Python 警告框架发出 Python 警告,让程序员可以选择性地查看这些扩展的使用情况。为了使此功能有用,必须标准化警告消息,以便能够屏蔽它们。以下将这些标准消息称为警告消息。
- Cursor.rownumber
- 此只读属性应提供游标在结果集中的当前 0 索引,如果无法确定索引,则应提供
None
。索引可以看作游标在序列(结果集)中的索引。下一个获取操作将获取该序列中由 .rownumber 索引的行。
警告消息:“使用了 DB-API 扩展 cursor.rownumber”
- Connection.Error,Connection.ProgrammingError 等。
- DB API 标准定义的所有异常类都应作为属性暴露在 Connection 对象上(除了在模块范围内可用)。
这些属性简化了多连接环境中的错误处理。
警告消息:“使用了 DB-API 扩展 connection.<exception>”
- Cursor.connection
- 此只读属性返回对创建游标的 Connection 对象的引用。
此属性简化了在多连接环境中编写多态代码。
警告消息:“使用了 DB-API 扩展 cursor.connection”
- Cursor.scroll(value [, mode=’relative’ ])
- 根据mode,将游标在结果集中滚动到新的位置。
如果 mode 为
relative
(默认),则 value 被视为结果集中当前位置的偏移量;如果设置为absolute
,则 value 表示绝对目标位置。如果滚动操作将超出结果集,则应抛出
IndexError
。在这种情况下,游标位置将被置为未定义状态(理想情况下是不移动游标)。注意
此方法应使用本机可滚动游标(如果可用),或者对于仅向前可滚动游标,回退到仿真。此方法可能会抛出 NotSupportedError 来表示数据库不支持特定操作(例如,向后滚动)。
警告消息:“使用了 DB-API 扩展 cursor.scroll()”
- Cursor.messages
- 这是一个 Python 列表对象,接口将所有来自底层数据库的此游标的消息(异常类、异常值)以元组形式追加到该列表中。
所有标准游标方法调用(在执行调用之前)都会清除该列表,除了 .fetch*() 调用会自动清除,以避免过度使用内存,也可以通过执行
del cursor.messages[:]
来清除该列表。数据库生成的的所有错误和警告消息都将放入此列表中,因此检查此列表允许用户验证方法调用的正确操作。
此属性的目的是消除对 Warning 异常的需要,因为 Warning 异常通常会造成问题(一些警告实际上只具有信息性字符)。
警告消息:“使用了 DB-API 扩展 cursor.messages”
- Connection.messages
- 与 Cursor.messages 相同,只是列表中的消息是面向连接的。
所有标准连接方法调用(在执行调用之前)都会自动清除该列表,以避免过度使用内存,也可以通过执行
del connection.messages[:]
来清除该列表。警告消息:“使用了 DB-API 扩展 connection.messages”
- Cursor.next()
- 使用与 .fetchone() 相同的语义,从当前正在执行的 SQL 语句中返回下一行。当结果集耗尽时,对于 Python 版本 2.2 及更高版本,将抛出
StopIteration
异常。早期版本没有StopIteration
异常,因此该方法应改为抛出IndexError
。警告消息:“使用了 DB-API 扩展 cursor.next()”
- Cursor.__iter__()
- 返回 self,使游标与迭代协议兼容 [8]。
警告消息:“使用了 DB-API 扩展 cursor.__iter__()”
- Cursor.lastrowid
- 此只读属性提供最后修改行的 rowid(大多数数据库仅在执行单个
INSERT
操作时返回 rowid)。如果操作未设置 rowid 或数据库不支持 rowid,则此属性应设置为None
。如果最后执行的语句修改了不止一行(例如,使用
INSERT
与.executemany()
),则.lastrowid
的语义将被定义为未定义。警告消息:“使用了 DB-API 扩展 cursor.lastrowid”
- Connection.autocommit
- 用于查询和设置连接的自动提交模式的属性。
如果连接以自动提交(非事务性)模式运行,则返回
True
。如果连接以手动提交(事务性)模式运行,则返回False
。将该属性设置为
True
或False
将相应地调整连接的模式。将设置从
True
更改为False
(禁用自动提交)将使数据库离开自动提交模式并启动一个新的事务。从False
更改为True
(启用自动提交)在处理挂起的事务时具有依赖于数据库的语义。 [12]弃用通知:即使几个数据库模块同时实现了此属性的读和写特性,通过写入属性来设置自动提交模式已弃用,因为这可能会导致 I/O 和相关异常,从而难以在异步上下文中实现。 [13]
警告消息:“使用了 DB-API 扩展 connection.autocommit”
可选的错误处理扩展
核心 DB API 规范只介绍了一组异常,这些异常可以抛出以向用户报告错误。在某些情况下,异常可能会对程序的流程造成太大干扰,甚至可能导致执行无法进行。
为了处理这些情况,并为了简化处理数据库时的错误处理,数据库模块作者可以选择实现用户定义的错误处理程序。本节描述了一种定义这些错误处理程序的标准方法。
- Connection.errorhandler,Cursor.errorhandler
- 读写属性,引用在遇到错误情况时要调用的错误处理程序。
处理程序必须是 Python 可调用对象,它接受以下参数
errorhandler(connection, cursor, errorclass, errorvalue)
其中 connection 是对游标操作的连接的引用,cursor 是对游标的引用(如果错误不适用于游标,则为
None
),errorclass 是要使用 errorvalue 作为构造参数来实例化的错误类。标准错误处理程序应将错误信息添加到相应的
.messages
属性中(Connection.messages 或 Cursor.messages),并抛出由给定的 errorclass 和 errorvalue 参数定义的异常。如果没有设置
.errorhandler
(该属性为None
),则应应用上述标准错误处理方案。警告消息:“使用了 DB-API 扩展 .errorhandler”
游标应在游标创建时从其连接对象继承 .errorhandler
设置。
可选的两阶段提交扩展
许多数据库支持两阶段提交 (TPC),它允许跨多个数据库连接和其他资源管理事务。
如果数据库后端提供了对两阶段提交的支持,并且数据库模块作者希望公开这种支持,则应实现以下 API。如果只有在运行时才能检查数据库后端对两阶段提交的支持,则应抛出 NotSupportedError。
TPC 事务 ID
由于许多数据库遵循 XA 规范,因此事务 ID 由三个部分组成
- 格式 ID
- 全局事务 ID
- 分支限定符
对于特定全局事务,前两个部分对所有资源都应相同。全局事务中的每个资源都应分配一个不同的分支限定符。
各个组件必须满足以下条件
- 格式 ID:一个非负的 32 位整数。
- 全局事务 ID 和分支限定符:长度不超过 64 个字符的字节串。
事务 ID 是使用 .xid() 连接方法创建的
- .xid(format_id, global_transaction_id, branch_qualifier)
- 返回一个适合传递给该连接的 .tpc_*() 方法的事务 ID 对象。
如果数据库连接不支持 TPC,则会引发 NotSupportedError。
由 .xid() 返回的对象类型未定义,但它必须提供序列行为,允许访问三个组件。符合规范的数据库模块可以选择用元组而不是自定义对象来表示事务 ID。
TPC 连接方法
- .tpc_begin(xid)
- 使用给定的事务 ID xid 开始 TPC 事务。
此方法应该在事务之外调用(即 自上次 .commit() 或 .rollback() 之后,没有任何内容可能已执行)。
此外,在 TPC 事务内调用 .commit() 或 .rollback() 是错误的。如果应用程序在活动 TPC 事务期间调用 .commit() 或 .rollback(),则会引发 ProgrammingError。
如果数据库连接不支持 TPC,则会引发 NotSupportedError。
- .tpc_prepare()
- 执行使用 .tpc_begin() 启动的事务的第一阶段。如果此方法在 TPC 事务之外调用,则应引发 ProgrammingError。
在调用 .tpc_prepare() 之后,在调用 .tpc_commit() 或 .tpc_rollback() 之前,不能执行任何语句。
- .tpc_commit([ xid ])
- 当不带参数调用时,.tpc_commit() 提交之前使用 .tpc_prepare() 准备好的 TPC 事务。
如果在 .tpc_prepare() 之前调用 .tpc_commit(),则会执行单阶段提交。如果只有一个资源参与全局事务,事务管理器可以选择这样做。
当带事务 ID xid 调用时,数据库会提交给定事务。如果提供无效的事务 ID,则会引发 ProgrammingError。此形式应在事务之外调用,并旨在用于恢复。
在返回时,TPC 事务结束。
- .tpc_rollback([ xid ])
- 当不带参数调用时,.tpc_rollback() 回滚 TPC 事务。它可以在 .tpc_prepare() 之前或之后调用。
当带事务 ID xid 调用时,它会回滚给定事务。如果提供无效的事务 ID,则会引发 ProgrammingError。此形式应在事务之外调用,并旨在用于恢复。
在返回时,TPC 事务结束。
- .tpc_recover()
- 返回适合与
.tpc_commit(xid)
或.tpc_rollback(xid)
一起使用的待处理事务 ID 列表。如果数据库不支持事务恢复,它可能会返回一个空列表或引发 NotSupportedError。
常见问题解答
数据库 SIG 通常会看到关于 DB API 规范的重复问题。本节介绍了人们有时对规范会遇到的一些问题。
问题
如何从 .fetch*() 返回的元组构造字典?
答案
有几个现有的工具可以提供用于此任务的帮助程序。它们中的大多数使用将游标属性 .description 中定义的列名用作行字典中键的基础的方法。
请注意,没有将 DB API 规范扩展到也支持 .fetch*() 方法的字典返回值的原因是,这种方法有几个缺点
- 一些数据库不支持区分大小写的列名,或自动将它们转换为全小写或全大写字符。
- 结果集中的由查询生成的列(例如,使用 SQL 函数)不映射到表列名,并且数据库通常以非常数据库特定的方式为这些列生成名称。
因此,通过字典键访问列在数据库之间有所不同,并使编写可移植代码变得不可能。
与版本 1.0 相比,版本 2.0 的主要变化
Python 数据库 API 2.0 与 1.0 版本相比引入了一些重大更改。由于其中一些更改会导致现有的基于 DB API 1.0 的脚本中断,因此主版本号已调整以反映此更改。
以下是 1.0 到 2.0 的最重要更改
- 对单独的 dbi 模块的需求已被删除,其功能已合并到模块接口本身。
- 为日期/时间值添加了新的构造函数和 类型对象,
RAW
类型对象已重命名为BINARY
。结果集应该涵盖现代 SQL 数据库中常见的全部基本数据类型。 - 添加了新的常量(apilevel、threadsafety、paramstyle)和方法(.executemany()、.nextset())以提供更好的数据库绑定。
- 调用存储过程所需的 .callproc() 的语义现在已明确定义。
- .execute() 返回值的定义已更改。以前,返回值是基于 SQL 语句类型(这很难正确实现)——它现在未定义;改用更灵活的 .rowcount 属性。模块可以自由地返回旧样式的返回值,但这些不再由规范强制执行,应被视为数据库接口依赖项。
- 基于类的 异常 已合并到规范中。模块实现者可以自由地通过对定义的异常类进行子类化来扩展本规范中定义的异常布局。
发布后对 DB API 2.0 规范的补充
- 指定了对核心功能集的额外可选 DB API 扩展。
未解决问题
尽管 2.0 版规范澄清了 1.0 版中遗留的许多问题,但仍有一些遗留问题需要在将来的版本中解决
- 为 .nextset() 定义一个有用的返回值,用于有新结果集可用的情况。
- 集成 decimal 模块
Decimal
对象,以用作无损货币和十进制交换格式。
脚注
鸣谢
衷心感谢 Andrew Kuchling,他在 2001 年将 Python 数据库 API 规范 2.0 从最初的 HTML 格式转换为 PEP 格式。
衷心感谢 James Henstridge,他在 2008 年领导了关于标准化两阶段提交 API 扩展的讨论。
衷心感谢 Daniele Varrazzo,他在 2012 年将规范从文本 PEP 格式转换为 ReST PEP 格式,这使得可以链接到各种部分。
版权
本文件已置于公共领域。
来源: https://github.com/python/peps/blob/main/peps/pep-0249.rst
最后修改: 2023-09-09 17:39:29 GMT