J'essaie de créer une base de données sqlite3 en mémoire en utilisant la classe twisted.enterprise.adbapi.ConnectionPool
de Twisted. Mon test cas est la suivante:Pourquoi ma table en mémoire de sqlite3 n'existe-t-elle pas après l'exécution d'une requête CREATE?
#! /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)
L'exécution du script ci-dessus produit l'erreur suivante: sqlite3.OperationalError: no such table: ajxp_index
Là où les choses deviennent étranges est si nous remplaçons :memory:
avec un chemin vers un fichier sur un stockage persistant, par exemple: /tmp/foo.sqlite
. Sous cette condition, le script s'exécute comme prévu.
En outre, exécutant les mêmes requêtes SQL en utilisant le module sqlite3
dans les courses de la bibliothèque standard comme prévu:
import sqlite3
conn = sqlite3.connect(":memory:")
for sql in sql_init: # same commands as in above example
conn.execute(sql)
Qu'est-ce qui se passe? Est-ce un bug dans Twisted, ou est-ce que je fais quelque chose de mal?
EDIT:
Selon la suggestion de notorious.no, j'ai mis à jour mon exemple à utiliser cp.runInteraction
, mais le résultat reste le même:
@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))
EDIT 2
D'accord, ce semble fonctionner:
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))