Это сложно описать или показать много кода, но я попробую. По сути, у меня многопоточное настольное приложение, которое часто обрабатывает добавление/удаление/изменение таблиц в потоках. Из того, что я читал, я должен использовать scoped_session и передавать это для различных потоков, чтобы выполнить работу (я думаю?). Вот некоторые примеры базового кода:Режиссированные сессии, заканчивающиеся на SQLAlchemy?
class SQL():
def __init__(self):
self.db = create_engine('mysql+mysqldb://thesqlserver')
self.metadata = MetaData(self.db)
self.SessionObj = scoped_session(sessionmaker(bind=self.db, autoflush=True))
db = SQL()
session = db.SessionObj()
someObj = Obj(val, val2)
session.add(someObj)
session.commit()
Этот класс является тем, что я использую в качестве общего доступа к SQL-материалам. После создания нового сеанса, выполняя запрос и обновление/добавление к нему, на session.commit(), я получаю следующее сообщение об ошибке:
Traceback (most recent call last):
File "core\taskHandler.pyc", line 42, in run
File "core\taskHandler.pyc", line 184, in addTasks
File "core\sqlHandler.pyc", line 35, in commit
File "sqlalchemy\orm\session.pyc", line 624, in rollback
File "sqlalchemy\orm\session.pyc", line 338, in rollback
File "sqlalchemy\orm\session.pyc", line 369, in _rollback_impl
File "sqlalchemy\orm\session.pyc", line 239, in _restore_snapshot
File "sqlalchemy\orm\state.pyc", line 252, in expire
AttributeError: 'NoneType' object has no attribute 'expire'
Тогда следующий, если очередная попытка SQL проходит через:
Traceback (most recent call last):
File "core\taskHandler.pyc", line 44, in run
File "core\taskHandler.pyc", line 196, in deleteTasks
File "sqlalchemy\orm\query.pyc", line 2164, in scalar
File "sqlalchemy\orm\query.pyc", line 2133, in one
File "sqlalchemy\orm\query.pyc", line 2176, in __iter__
File "sqlalchemy\orm\query.pyc", line 2189, in _execute_and_instances
File "sqlalchemy\orm\query.pyc", line 2180, in _connection_from_session
File "sqlalchemy\orm\session.pyc", line 729, in connection
File "sqlalchemy\orm\session.pyc", line 733, in _connection_for_bind
File "sqlalchemy\orm\session.pyc", line 249, in _connection_for_bind
File "sqlalchemy\orm\session.pyc", line 177, in _assert_is_active
sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back by a nested rollback() call. To begin a new transaction, issue Session.rollback() first.
Это примерно столько, сколько я знаю, и я думаю, что лучшее, что я могу описать. Любые идеи о том, что я есть предположительно здесь делать? Это все грязь для меня. Заранее спасибо!
Shucks. Ну, это потрясающий ответ, и я высоко ценю то, о чем вы сказали в пятом абзаце. Итак, чтобы подвести итог, то, что я должен делать, это создать новый сеанс для каждой серии задач, которые необходимо выполнить? В частности, я должен определить _new_ (сеанс или scoped_session?) Для каждого рабочего потока? По сути, у меня есть один большой поток, который запускает графический интерфейс и выполняет некоторые небольшие работы с SQL, а затем еще один рабочий поток, который обрабатывает более сложные/более длительные SQL-запросы/добавления/обновления. Еще раз спасибо за ответ! – Cryptite
Также, используя SQLAlchemy 0.7.7. Я думал, что понял, что вы сказали, и обновил код OP, чтобы отразить то, что я сейчас пытаюсь сделать, но это непременно приводит к тому, что _Nonetype не имеет атрибута «expire» при каждом выполнении 'session.commit()'. Выполняется фактическая задача SQL, и таблица прекрасно обновляется, но фиксация по-прежнему дает ошибку истечения срока действия. – Cryptite
, если у вас что-то непротиворечивое, тогда используйте его в краткой (очень короткой, очень ОЧЕНЬ короткой, не посторонней детали) тестовом случае и опубликуйте его в списке рассылки, я дам ему прогон и сделаю предложения. – zzzeek