У меня есть телеграмм-бот, и когда несколько пользователей одновременно выполняют какие-либо действия в нем, база данных выдает ошибку «Recursive use of cursors not allowed». Можно ли как-то решить эту проблему с помощью sqlite3, или она не поддерживает одновременное выполнение запросов? Если нет, то какие локальные (которые в одном файле) базы данных это поддерживают?
vo0ov programmer, эта ошибка вылетает при конкурентном доступе к курсору или соединению, а значит у вас кто-то из них открыт один раз, сохранён в глобальную переменную и используется в разных запросах.
vo0ov programmer, стараться выполнять запросы в БД как можно быстрее и сразу закрывать соединение. Ещё можно попробовать открывать БД в wal-режиме. Ещё можно организовать очередь записи, но это уже затрах, при той интенсивности запросов, когда такие методы нужны, лучше уже переходить на взрослые СУБД с нормальной поддержкой конкурентности.
vo0ov programmer, только с сервером. Умение обрабатывать конкурентные запросы неотъемлемо от сетевого доступа, файловые СУБД пригодны только к для однопользовательских или маленьких приложений.
Сергей Горностаев, допустим есть хост с MySQL. Как включить поддержку одновременных запросов? Или она уже встроена и можно просто писать cur.execute(...)? Как мне кажется нужно писать async/await.
config = dict(
host ="localhost",
user ="user",
passwd ="password",
database = "mydb"
)
def func(script):
with mysql.connector.connect(**config) as connection:
with connection.cursor() as cursor:
cursor.execute(script)
какие локальные (которые в одном файле) базы данных это поддерживают?
1. Можно использовать sqlite3, но нужно будет настроить очереди на взаимодействие с бд, либо использовать sqlalchemy, который имеет поддержку пула соединений.
2. Другие файловые бд не вижу смысла использовать, т.к. скорее всего настройка таких не популярных бд будет сложнее, чем п1.
import threading
import queue
from sqlalchemy import create_engine
# Создаем очередь запросов
query_queue = queue.Queue()
# Функция для выполнения запросов
def execute_queries():
# Создаем движок SQLAlchemy
engine = create_engine('sqlite:///db.sqlite3', connect_args={'check_same_thread': False})
while True:
# Получаем запрос из очереди
query = query_queue.get()
if query is None:
break
# Выполняем запрос
with engine.connect() as connection:
connection.execute(query)
# Сообщаем, что запрос выполнен
query_queue.task_done()
# Запускаем поток для выполнения запросов
query_thread = threading.Thread(target=execute_queries)
query_thread.start()
# Помещаем запросы в очередь
query_queue.put("INSERT INTO table_name (column1, column2) VALUES (value1, value2)")
query_queue.put("SELECT * FROM table_name WHERE condition")
# Ждем завершения всех запросов
query_queue.join()
# Завершаем поток после выполнения всех запросов
query_queue.put(None)
query_thread.join()