Подключение к базе данных памяти SQLite из отдельного файла (Python)

приложение, которое я создаю, потребует единой базы данных памяти 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 = Ложь

например

db = sqlite3.connect('file:my_db?mode=memory&cache=shared', check_same_thread=False, uri=True)
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
1 649
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы открыли названный, в памяти соединение с базой данных с общим кешем. Да, вы можете поделиться кешем в этой базе данных, но только если вы используете то же имя. Это означает, что вам нужно использовать полную схему 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')]

Другой способ добиться этого - открыть соединение с базой данных в основном коде перед вызовом функции; который создает первое соединение с базой данных в памяти, а открытие и закрытие дополнительных соединений не приведет к потере изменений.

Из документации:

When an in-memory database is named in this way, it will only share its cache with another connection that uses exactly the same name.

Если вы не хотели, чтобы база данных просто находилась в памяти, и хотели, чтобы таблица была зафиксирована на диске (чтобы она была там в следующий раз, когда вы откроете соединение), отбросьте компонент mode=memory.

Другие вопросы по теме