Python sqlite3.Connection.text_factory 属性
上次修改时间:2025 年 4 月 15 日
本篇综合指南探讨了 Python 的 sqlite3.Connection.text_factory
属性,它控制着 SQLite TEXT 值如何转换为 Python 对象。我们将涵盖基本用法、自定义和实际示例。
基本定义
sqlite3.Connection
对象的 text_factory
属性决定了数据库中的 TEXT 值如何转换为 Python 对象。 默认情况下,它返回 Unicode 字符串 (str
)。
主要特征:它是一个可调用对象,接受 bytes 对象,可以在运行时更改,并影响所有后续查询。 它对于处理 SQLite 数据库中的文本编码至关重要。
默认文本工厂行为
此示例演示了默认行为,其中 TEXT 值作为 Python Unicode 字符串返回。
import sqlite3 with sqlite3.connect(':memory:') as conn: conn.execute("CREATE TABLE test (id INTEGER, text_data TEXT)") conn.execute("INSERT INTO test VALUES (1, 'Hello World')") # Default text_factory returns str (Unicode) cursor = conn.cursor() cursor.execute("SELECT text_data FROM test WHERE id = 1") result = cursor.fetchone()[0] print(type(result), result) # <class 'str'> Hello World
默认的 text_factory
将 SQLite TEXT 值转换为 Python str
对象。 这是最常见且推荐用于大多数应用程序的设置。
该示例使用内存数据库为了简单起见,演示了文本数据的自动 Unicode 转换。
返回字节而不是 Unicode
设置 text_factory = bytes
使 TEXT 值返回为原始 bytes 对象,而不是 Unicode 字符串。
import sqlite3 with sqlite3.connect(':memory:') as conn: conn.text_factory = bytes conn.execute("CREATE TABLE test (id INTEGER, text_data TEXT)") conn.execute("INSERT INTO test VALUES (1, 'Hello World')") cursor = conn.cursor() cursor.execute("SELECT text_data FROM test WHERE id = 1") result = cursor.fetchone()[0] print(type(result), result) # <class 'bytes'> b'Hello World'
此示例演示了如何从 TEXT 列中获取原始字节。 当您需要 SQLite 中存储的确切二进制表示时,bytes
工厂非常有用。
请注意,bytes 对象包含字符串的 UTF-8 编码版本,这是 SQLite 用于 TEXT 的内部存储格式。
自定义文本工厂函数
您可以定义一个自定义函数,以在 TEXT 值成为 Python 对象之前以特定方式对其进行处理。
import sqlite3 def upper_case_factory(b): return b.decode('utf-8').upper() with sqlite3.connect(':memory:') as conn: conn.text_factory = upper_case_factory conn.execute("CREATE TABLE test (id INTEGER, text_data TEXT)") conn.execute("INSERT INTO test VALUES (1, 'Hello World')") cursor = conn.cursor() cursor.execute("SELECT text_data FROM test WHERE id = 1") result = cursor.fetchone()[0] print(result) # HELLO WORLD
此自定义工厂将所有 TEXT 值转换为大写。 该函数接收来自 SQLite 的原始字节,并返回处理后的 Python 对象。
自定义工厂对于数据转换非常强大,但应谨慎使用,因为它们会影响所有 TEXT 列检索。
处理不同的编码
text_factory
可用于处理存储在 SQLite 数据库中的非 UTF-8 文本编码。
import sqlite3 def latin1_decoder(b): return b.decode('latin-1') with sqlite3.connect(':memory:') as conn: conn.text_factory = latin1_decoder # Store Latin-1 encoded text directly as bytes conn.execute("CREATE TABLE test (id INTEGER, text_data TEXT)") conn.execute("INSERT INTO test VALUES (1, ?)", ('Héllö Wørld'.encode('latin-1'),)) cursor = conn.cursor() cursor.execute("SELECT text_data FROM test WHERE id = 1") result = cursor.fetchone()[0] print(result) # Héllö Wørld
此示例演示了如何处理 Latin-1 编码的文本。 自定义工厂使用正确的编码来解码字节。
当使用旧数据库或特定编码要求时,自定义文本工厂提供必要的灵活性。
将 Lambda 用作文本工厂
对于简单的转换,lambda 函数可以作为简洁的 text_factory
。
import sqlite3 with sqlite3.connect(':memory:') as conn: conn.text_factory = lambda b: b.decode('utf-8').strip().title() conn.execute("CREATE TABLE test (id INTEGER, text_data TEXT)") conn.execute("INSERT INTO test VALUES (1, ' hello world ')") cursor = conn.cursor() cursor.execute("SELECT text_data FROM test WHERE id = 1") result = cursor.fetchone()[0] print(result) # Hello World
此 lambda 函数修剪空格并将所有 TEXT 值转换为首字母大写。 Lambda 对于简单的一行转换非常方便。
对于更复杂的处理,通常使用命名函数(如前面的示例)更易于维护。
禁用文本转换
设置 text_factory = None
会禁用所有转换,返回与 SQLite 中存储的完全一样的原始字节。
import sqlite3 with sqlite3.connect(':memory:') as conn: conn.text_factory = None conn.execute("CREATE TABLE test (id INTEGER, text_data TEXT)") conn.execute("INSERT INTO test VALUES (1, 'Hello World')") cursor = conn.cursor() cursor.execute("SELECT text_data FROM test WHERE id = 1") result = cursor.fetchone()[0] print(type(result), result) # <class 'bytes'> b'Hello World'
使用 text_factory = None
,TEXT 值将作为原始字节返回,而无需进行任何解码尝试。 这类似于使用 bytes
,但没有 str
会执行的自动 UTF-8 解码。
当您需要手动处理编码或者使用存储在 TEXT 列中的二进制数据时,此方法非常有用。
最佳实践
- 使用默认 str 进行 Unicode: 最适合大多数应用程序
- 小心处理编码: 明确文本编码
- 考虑性能: 自定义工厂会增加开销
- 记录自定义工厂: 使其他开发人员清楚地了解行为
- 彻底测试: 尤其是在使用非 UTF-8 数据时
资料来源
作者
列出所有 Python 教程。