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 教程。