为什么运行 CREATE 查询后我的 sqlite3 内存中表不存在?



我正在尝试使用 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 有帮助的文章

最新更新