我正在尝试使用 Twisted 的 twisted.enterprise.adbapi.ConnectionPool
类创建一个内存中的 sqlite3 数据库。 我的测试用例如下:
#! /usr/bin/env python
from twisted.internet import task
from twisted.internet import defer
from twisted.enterprise.adbapi import ConnectionPool
sql_init = (
"CREATE TABLE ajxp_index ( node_id INTEGER PRIMARY KEY AUTOINCREMENT );",
"INSERT INTO ajxp_index (node_id) VALUES (9001);",
)
@task.react
@defer.inlineCallbacks
def main(reactor):
cp = ConnectionPool("sqlite3", ":memory:", check_same_thread=False)
for sql in sql_init:
print(sql)
yield cp.runQuery(sql)
运行上述脚本会产生以下错误:sqlite3.OperationalError: no such table: ajxp_index
事情变得奇怪的是,如果我们用持久存储上的文件的路径替换:memory:
,例如: /tmp/foo.sqlite
. 在这种情况下,脚本将按预期执行。
此外,使用标准库中的 sqlite3
模块运行相同的 SQL 查询将按预期运行:
import sqlite3
conn = sqlite3.connect(":memory:")
for sql in sql_init: # same commands as in above example
conn.execute(sql)
什么给? 这是 Twisted 中的错误,还是我做错了什么?
编辑:
根据 notorious.no 的建议,我已经更新了我的示例以使用 cp.runInteraction
,但结果保持不变:
@task.react
@defer.inlineCallbacks
def main(reactor):
cp = ConnectionPool("sqlite3", ":memory:", check_same_thread=False)
for sql in sql_init:
print(sql)
yield cp.runInteraction(lambda cursor: cursor.execute(sql))
编辑 2
好的,这似乎有效:
def _interact(cursor, script):
cursor.executescript(script)
@task.react
@defer.inlineCallbacks
def main(reactor):
cp = ConnectionPool("sqlite3", ":memory:", check_same_thread=False)
yield cp.runInteraction(_interact, "n".join(sql_init))
你的代码不起作用,因为你正在做cp.runQuery
,相反,它应该是runInteraction
的。
cp.runInteraction(lambda cursor, stmt: cursor.execute(stmt))
我写了一篇可能对 https://notoriousno.blogspot.com/2016/08/twisted-klein-database-usage.html?m=1 有帮助的文章