要将任何字符串转换为SQLite标识符:
- 确保该字符串可以编码为UTF-8。
- 确保字符串不包含任何NUL字符。
- 全部替换
"
为""
。 - 将整个内容用双引号引起来。
import precsdef quote_identifier(s, errors="strict"): encodable = s.enpre("utf-8", errors).depre("utf-8") nul_index = encodable.find("x00") if nul_index >= 0: error = UnipreEnpreError("NUL-terminated utf-8", encodable, nul_index, nul_index + 1, "NUL not allowed") error_handler = precs.lookup_error(errors) replacement, _ = error_handler(error) encodable = encodable.replace("x00", replacement) return """ + encodable.replace(""", """") + """
给定一个字符串单个参数,它将转义并正确引用它或引发异常。第二个参数可以被用来指定在注册的任何错误处理程序的
precs模块。内置的是:
'strict':在编码错误的情况下引发异常 'replace':用适当的替换标记替换格式错误的数据,例如'?'或'ufffd' 'ignore':忽略格式错误的数据,并继续进行,恕不另行通知 'xmlcharrefreplace':替换为适当的XML字符参考(仅用于编码) 'backslashreplace':替换为反斜杠转义序列(仅用于编码)
这不会检查保留的标识符,因此,如果您尝试创建一个新
SQLITE_MASTER表,它不会阻止您。用法示例
观察与参考import sqlite3def test_identifier(identifier): "Tests an identifier to ensure it's handled properly." with sqlite3.connect(":memory:") as c: c.execute("CREATE TABLE " + quote_identifier(identifier) + " (foo)") assert identifier == c.execute("SELECT name FROM SQLITE_MASTER").fetchone()[0]test_identifier("'Héllo?'\nrt"Hello!" -☃") # workstest_identifier("北方话") # workstest_identifier(chr(0x20000)) # worksprint(quote_identifier("Fox00o!", "replace")) # prints "Fo?o!"print(quote_identifier("Fox00o!", "ignore")) # prints "Foo!"print(quote_identifier("Fox00o!")) # raises UnipreEnpreErrorprint(quote_identifier(chr(0xD800))) # raises UnipreEnpreError
SQLite标识符是
TEXT
,不是二进制。SQLITE_MASTER
常见问题解答中的模式- 当我给它不能被解码为文本的字节时,Python 2 SQLite API向我吼叫。
- Python 3 SQLite API要求查询是
str
,而不是bytes
。
SQLite标识符使用双引号引起来。
- SQLite理解的SQL
SQLite标识符中的双引号以两个双引号转义。
SQLite标识符保留大小写,但对ASCII字母不区分大小写。可以启用可识别unipre的大小写。
- SQLite常见问题#18
SQLite不支持字符串或标识符中的NUL字符。
- SQLite票证57c971fc74
sqlite3
只要可以将其正确编码为UTF-8,就可以处理任何其他unipre字符串。无效的字符串可能会导致Python 3.0和Python 3.1.2或其附近崩溃。Python 2接受了这些无效的字符串,但这被认为是一个错误。- Python问题#12569
- 模块/_sqlite/cursor.c
- 我测试了一堆。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)