Python sqlite3.Cursor.setinputsizes 方法
上次修改时间:2025 年 4 月 15 日
本指南探讨 Python 的 sqlite3.Cursor.setinputsizes 方法,它是 DB-API 2.0 规范的一部分,但在 SQLite 中未实现。
基本定义
setinputsizes 方法在 Python 的 DB-API 2.0 中定义为预定义参数绑定的内存区域的一种方式。 它旨在优化同一语句的重复执行。
在 SQLite 的实现中,此方法什么也不做,因为 SQLite 动态处理参数绑定。 该方法的存在是为了 API 兼容性,但不起作用。
方法签名
该方法的签名很简单:setinputsizes(sizes),其中 sizes 可以是序列或 None。 sizes 参数指定预期的数据类型。
尽管可以调用,但该方法在 SQLite 中不执行任何操作。 它的存在是为了保持与 DB-API 2.0 规范的兼容性。
基本用法
此示例演示了使用不同参数类型调用该方法。 尽管进行了调用,但它们对 SQLite 操作没有影响。
import sqlite3
with sqlite3.connect(':memory:') as conn:
with conn.cursor() as cur:
# These calls do nothing in SQLite
cur.setinputsizes(None)
cur.setinputsizes([sqlite3.TEXT, sqlite3.INTEGER])
cur.setinputsizes(50) # Arbitrary size
# Execute a query normally
cur.execute("CREATE TABLE test (id INTEGER, name TEXT)")
cur.execute("INSERT INTO test VALUES (?, ?)", (1, 'Alice'))
该示例表明,可以调用 setinputsizes,但不会影响后续操作。 SQLite 动态处理参数绑定。
使用 execute
此示例尝试在执行查询之前使用 setinputsizes。 该方法调用对执行没有影响。
import sqlite3
with sqlite3.connect(':memory:') as conn:
with conn.cursor() as cur:
cur.execute("CREATE TABLE data (id INTEGER, value REAL)")
# Set input sizes (no effect)
cur.setinputsizes([sqlite3.INTEGER, sqlite3.REAL])
# Insert data works the same with or without setinputsizes
cur.execute("INSERT INTO data VALUES (?, ?)", (1, 3.14159))
# Verify insertion
cur.execute("SELECT * FROM data")
print(cur.fetchone()) # (1, 3.14159)
无论是否调用 setinputsizes,数据插入的工作方式都相同。 SQLite 在执行时确定参数类型。
多种参数类型
此示例表明,SQLite 忽略提供给 setinputsizes 的类型提示,并自动处理类型转换。
import sqlite3
with sqlite3.connect(':memory:') as conn:
with conn.cursor() as cur:
cur.execute("CREATE TABLE items (id INTEGER, name TEXT, price REAL)")
# Set input sizes for different types (ignored)
cur.setinputsizes([sqlite3.INTEGER, sqlite3.TEXT, sqlite3.REAL])
# Insert with automatic type conversion
cur.execute("INSERT INTO items VALUES (?, ?, ?)",
('1', 42.99, '3.50')) # Note reversed types
# The values are stored correctly despite type hints
cur.execute("SELECT * FROM items")
print(cur.fetchone()) # (1, '42.99', 3.5)
无论 setinputsizes 调用如何,SQLite 都会执行类型转换。 该方法不会在 SQLite 中强制执行或影响类型处理。
使用 executemany
此示例演示了 setinputsizes 对使用 executemany 的批量操作没有影响。
import sqlite3
data = [
(1, 'Apple', 0.99),
(2, 'Banana', 0.59),
(3, 'Cherry', 1.99)
]
with sqlite3.connect(':memory:') as conn:
with conn.cursor() as cur:
cur.execute("CREATE TABLE products (id INTEGER, name TEXT, price REAL)")
# Set input sizes (no effect)
cur.setinputsizes([sqlite3.INTEGER, sqlite3.TEXT, sqlite3.REAL])
# Batch insert works normally
cur.executemany("INSERT INTO products VALUES (?, ?, ?)", data)
# Verify all rows inserted
cur.execute("SELECT COUNT(*) FROM products")
print(cur.fetchone()[0]) # 3
无论 setinputsizes 调用如何,executemany 操作都会正常进行。 SQLite 动态处理每个参数集。
使用自定义类型
此示例表明,setinputsizes 不会影响 SQLite 中的自定义类型适配器。
import sqlite3
import datetime
# Register custom adapter
sqlite3.register_adapter(datetime.date, lambda d: d.isoformat())
with sqlite3.connect(':memory:') as conn:
with conn.cursor() as cur:
cur.execute("CREATE TABLE events (id INTEGER, date TEXT)")
# Set input sizes (ignored)
cur.setinputsizes([sqlite3.INTEGER, sqlite3.TEXT])
# Custom type conversion still works
today = datetime.date.today()
cur.execute("INSERT INTO events VALUES (?, ?)", (1, today))
# Verify date stored correctly
cur.execute("SELECT date FROM events WHERE id = 1")
print(cur.fetchone()[0]) # ISO formatted date
无论 setinputsizes 调用如何,自定义日期适配器都能正常工作。 SQLite 的类型适配系统独立于此方法运行。
性能比较
此示例演示了 setinputsizes 在 SQLite 中没有提供任何性能优势,这与其他一些数据库系统不同。
import sqlite3
import time
def time_inserts(use_setinputsizes):
with sqlite3.connect(':memory:') as conn:
with conn.cursor() as cur:
cur.execute("CREATE TABLE nums (n INTEGER)")
if use_setinputsizes:
cur.setinputsizes([sqlite3.INTEGER])
start = time.time()
for i in range(1000):
cur.execute("INSERT INTO nums VALUES (?)", (i,))
conn.commit()
return time.time() - start
# Compare execution times
time_with = time_inserts(True)
time_without = time_inserts(False)
print(f"With setinputsizes: {time_with:.4f}s")
print(f"Without setinputsizes: {time_without:.4f}s")
执行时间将几乎相同,表明 setinputsizes 在 SQLite 中没有提供性能优化。
错误处理
此示例表明,setinputsizes 不会验证参数或影响 SQLite 中的错误处理。
import sqlite3
with sqlite3.connect(':memory:') as conn:
with conn.cursor() as cur:
cur.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, data TEXT)")
# These calls don't affect error handling
cur.setinputsizes([sqlite3.INTEGER, sqlite3.TEXT])
cur.setinputsizes("invalid") # Non-standard parameter
try:
# This will still raise an error
cur.execute("INSERT INTO test VALUES (?, ?)", ("text", 123))
except sqlite3.InterfaceError as e:
print(f"Error occurred: {e}")
该示例演示了 setinputsizes 不会阻止或影响 SQLite 中与类型相关的错误。 错误在执行期间引发。
最佳实践
- 不要依赖它: 该方法在 SQLite 中不起作用
- 专注于 execute(): SQLite 动态处理参数
- 使用类型适配器: 用于替代的自定义类型处理
- 保持兼容性: 如果编写 DB-API 代码,请包含它
- 记录它的缺失: 请注意它在 SQLite 中不起作用
资料来源
作者
列出所有 Python 教程。