У меня настоящая головная боль от попыток понять причину следующей проблемы. Мы используем комбинацию следующих библиотек:
- pyTelegramBotAPI для обработки запросов многопоточным способом.
- SQLAlchemy
- sqlite
SQLAlchemy
сначала использовал NullPool
, а теперь настроен на использование QueuePool
. Я также использую следующую идиому, чтобы запустить новый сеанс БД для каждого потока (насколько я понимаю)
Session = sessionmaker(bind=create_engine(classes.db_url, poolclass=QueuePool))
@contextmanager
def session_scope():
session = Session()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
@bot.message_handler(content_types=['document'])
def method_handler:
with session_scope() as session:
do_database_stuff_here(session)
Тем не менее, я все еще получаю это раздражающее исключение: (sqlite3.ProgrammingError) SQLite objects created in a thread can only be used in that same thread
Любые идеи? ;) В частности, я не понимаю, как другой протектор может оказаться где-то между операциями БД... это, вероятно, причина надоедливого исключения
обновление 1: если я изменю poolclass
на SingletonThreadPool
, то ошибок больше не будет. Однако в документации SQLAlchemy
говорится, что это не массовое производство.
NullPool
, когда говоритеNullThreadPool
? Почему вам нужно использоватьQueuePool
? - person xli   schedule 22.10.2016QueuePool
? В документах совершенно ясно, что вы можете используйтеNullPool
,SingletonThreadPool
илиStaticPool
. - person Peter Brittain   schedule 23.10.2016NullPool
;) спасибо за исправление. Идея использованияQueuePool
заключалась в том, чтобы одновременно иметь несколько потоков (чтения). Почему это было бы неправильно? @xli, @Peter Brittain, реализацияSqlAlchemy
по умолчанию используетNullPool
, но при ее использовании я получаю исключения (как указано выше). Я понятия не имею, почему я их получаю, так как с помощью @contextmanager должно быть гарантировано, что я открываю одно соединение для каждого потока... - person d56   schedule 23.10.2016QueuePool
, но она исчезла сNullPool
. Может быть, у вас есть несколько потоков в вашем блокеwith
, или вы могли бы описать, что вы там делаете? - person xli   schedule 23.10.2016method_handler()
обращаются несколько потоков, но внутриdo_database_stuff_here()
нет вызовов новых потоков. Вот почему я не понимаю, почему это не работает. Но почему вы получаете ошибку сQueuePool
? согласно моим рассуждениям, хотя потоки используются повторно, все же есть один поток, обслуживающийmethod_handler()
, не так ли? - person d56   schedule 24.10.2016QueuePool
будет повторно использовать соединения и передавать то же соединение другому потоку. НоNullPool
следует избегать этой проблемы, потому что он каждый раз устанавливает новое соединение, а использованиеNullPool
привело к тому, что ошибка исчезла, когда я ее воспроизвел. - person xli   schedule 24.10.2016NullPool
. Хотя один вопрос в сторону. Означает ли использованиеwith session_scope() as session
, что у меня здесь есть блокирующий сегмент кода, покаNullPool
используется для соединения с каким-то другим потоком? Я читал, что сегодня Sqlite использует WAL для одновременного чтения. Есть ли способ активировать его в SQLAlchemy - person d56   schedule 26.10.2016with ... session
является довольно продолжительным сегментом, в котором происходит больше, чем просто соединение с БД (которое я не могу отделить) - person d56   schedule 26.10.2016NullPool
сделала свое дело! - person d56   schedule 14.11.2016