通过Python设置SQLite数据库的(默认)编码

5
我希望通过Python驱动程序创建一个SQLite数据库。由于应用程序将在不同的操作系统上运行,因此我希望明确指定SQLite数据库中文本的编码(默认情况下)。显然,我只能使用此命令在创建数据库之前执行此操作(请参见SQLite文档):
PRAGMA encoding = "UTF-8";

我的问题是,Python创建/连接数据库的方式没有明确指定(至少在我理解的范围内)在创建数据库之前设置PRAGMA(如编码)的方法(Python docs)。
因此,在创建数据库之前/期间,是否有任何通过Python SQlite驱动程序指定编码的方法?
我目前唯一看到的解决方法似乎有点hacky,就是通过Python运行Shell命令,但由于SQLite CLI未安装在计算机上,这不是一个选项。

我能想到的最接近的是text_factory,但你已经在实例化连接时创建了数据库。事实上,我的建议可能不太适合你正在尝试做的事情,但这是值得一看的东西。 - roganjosh
@roganjosh 我想过了,但是Text Factory是应用程序和数据库之间的网关。因此,我无法控制数据库保存的内容(以哪种编码方式) ,只能控制如何读取数据.... 至少如果我理解正确的话。 - Sergej Herbert
他们有C API https://www.sqlite.org/c3ref/open.html - avram
据我所见,PRAGMA encoding 是对整个数据库进行一次性永久更改。连接到数据库并执行 PRAGMA 应该可以为所有后续表完成您要查找的操作。既然如此,看起来 API 没有任何其他规定。 - roganjosh
不,我现在更倾向于你的解释,打算尝试测试一些东西。 - roganjosh
1个回答

5
您可以先创建数据库,然后再更改编码方式。
>>> import sqlite3
>>> conn = sqlite3.connect('example.db')
>>> c = conn.cursor()
>>> c.execute('pragma encoding')
<sqlite3.Cursor object at 0x7fa641241e30>
>>> rows = c.fetchall()
>>> for row in rows:
...     print(row)
... 
('UTF-8',)
>>> c.execute('pragma encoding=UTF16')
<sqlite3.Cursor object at 0x7fa641241b20>
>>> c.execute('pragma encoding')
<sqlite3.Cursor object at 0x7fa641241e30>
>>> rows = c.fetchall()
>>> for row in rows:
...     print(row)
... 
('UTF-16le',)

请注意,需要编辑数据库才能使这些更改永久生效,例如:
>>> sql_create_projects_table = """ CREATE TABLE IF NOT EXISTS projects (
...                                         id integer PRIMARY KEY,
...                                         name text NOT NULL,
...                                         begin_date text,
...                                         end_date text
...                                     ); """
>>> c.execute(sql_create_projects_table)
<sqlite3.Cursor object at 0x7f441ce90e30>
>>> rows = c.fetchall()
>>> for row in rows:
...     print(row)
...
>>> sql = ''' INSERT INTO projects(name,begin_date,end_date)
...               VALUES(?,?,?) '''
>>> project = ('Cool App with SQLite & Python', '2015-01-01', '2015-01-30');
>>> c.execute(sql, project)
<sqlite3.Cursor object at 0x7f441ce90e30>

如果您没有添加表格,编码将会回退到默认值。希望这能够帮助您。

1
我无法让它工作:https://pastebin.com/4Dst51Fd。编码仅适用于单个会话,而且它只是回到了UTF-8。在我尝试更改它之前,它已经回到了UTF-8。 - roganjosh
1
嗨,这对我有效,请在关闭之前尝试添加表格和数据。 - Jonathan R
关闭您的连接,重新建立它,然后查看是否获得相同的结果。您可以在一个会话中运行所有这些操作。 - roganjosh
请点击以下链接查看编程相关内容的中文翻译:https://pastebin.com/XBfnnjeV 这是一些虚假数据。关闭/重新建立连接后,编码仍然保持不变。 - Jonathan R
1
对我来说似乎可以工作(如果我添加一个表格)。这似乎会使编码更改变为永久性的。我将继续进行一些实验,如果它仍然有效,我将标记答案为已接受。 - Sergej Herbert
1
@JonathanR 您的示例对我很有效,我会将其标记为已接受的解决方案。您能否编辑您的答案以包括创建表格的“hack”? - Sergej Herbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接