【问题标题】:Connect to SQLite Memory Database from seperate file (Python)从单独的文件(Python)连接到 SQLite 内存数据库
【发布时间】:2018-12-29 13:25:42
【问题描述】:

我正在构建的应用程序需要一个单独的例程和线程需要访问的 sqlite 内存数据库。我很难做到这一点。

我明白:

file:my_db?mode=memory&cache=shared', uri=True

应该创建一个可以通过单独的连接修改和访问的内存数据库。

这是我返回错误的测试: “sqlite3.OperationalError:没有这样的表:my_table”

下面的代码保存为“test_create.py”:

import sqlite3

def create_a_table():
    db = sqlite3.connect('file:my_db?mode=memory&cache=shared', uri=True)
    cursor = db.cursor()

    cursor.execute('''
        CREATE TABLE my_table(id INTEGER PRIMARY KEY, some_data TEXT)
    ''')

    db.commit()
    db.close()

上面的代码在单独的文件中导入到下面的代码中:

import sqlite3
import test_create

test_create.create_a_table()
db = sqlite3.connect('file:my_db')
cursor = db.cursor()

# add a row of data
cursor.execute('''INSERT INTO my_table(some_data) VALUES(?)''', ("a bit of data",))
db.commit()

上面的代码工作正常,写在一个文件中。谁能建议我如何将代码保存在单独的文件中,这有望让我建立多个单独的连接?

注意:我不保存数据库。谢谢。

编辑:如果您想使用线程,请确保启用以下选项。 check_same_thread=False

例如

db = sqlite3.connect('file:my_db?mode=memory&cache=shared', check_same_thread=False, uri=True)

【问题讨论】:

    标签: python sqlite


    【解决方案1】:

    您打开了named, in-memory database connection with shared cache。是的,您可以共享该数据库上的缓存,但前提是您使用完全相同的名称。这意味着您需要使用完整的 URI 方案!

    如果您使用db = sqlite3.connect('file:my_db?mode=memory&cache=shared', uri=True) 连接,则进程中的任何其他连接都可以看到同一张表,前提是原始连接仍处于打开状态,并且您不介意该表是“私有的” ',仅在内存中,对使用不同名称的其他进程或连接不可用。当与数据库的最后一个连接关闭时,表就消失了。

    因此,您还需要在其他模块中保持连接打开才能正常工作!

    例如,如果您将模块更改为使用全局连接对象:

    db = None
    
    def create_a_table():
        global db
        if db is None:
            db = sqlite3.connect('file:my_db?mode=memory&cache=shared', uri=True)
    
        with db:
            cursor = db.cursor()
    
            cursor.execute('''
                CREATE TABLE my_table(id INTEGER PRIMARY KEY, some_data TEXT)
            ''')
    

    然后使用那个模块,表格就在那里:

    >>> import test_create
    >>> test_create.create_a_table()
    >>> import sqlite3
    >>> db = sqlite3.connect('file:my_db?mode=memory&cache=shared', uri=True)
    >>> with db:
    ...     cursor = db.cursor()
    ...     cursor.execute('''INSERT INTO my_table(some_data) VALUES(?)''', ("a bit of data",))
    ...
    <sqlite3.Cursor object at 0x100d36650>
    >>> list(db.cursor().execute('select * from my_table'))
    [(1, 'a bit of data')]
    

    实现这个的另一种方法是在调用函数之前在主代码中打开一个数据库连接;这会创建到内存数据库的第一个连接,并且打开和关闭其他连接不会导致更改丢失。

    来自文档:

    当内存数据库以这种方式命名时,它只会与另一个使用完全相同名称的连接共享其缓存。

    如果您的意思不是让数据库只在内存中,并且您希望将表提交到磁盘(下次打开连接时就在那里),请删除mode=memory 组件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-17
      • 2021-10-31
      • 2020-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多