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

Why doesn't my sqlite3 in-memory table exist after running a CREATE query?

我正在尝试使用 Twisted 的 twisted.enterprise.adbapi.ConnectionPool class 创建内存中的 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))

我写了一个 post 可能会有帮助 https://notoriousno.blogspot.com/2016/08/twisted-klein-database-usage.html?m=1