1
我發現自己在sqlalchemy重複了很多,我想知道什麼是最好的方式來處理它?
try:
#do some database query
db_session.commit()
except: #some exception handling
db_session.rollback()
我發現自己在sqlalchemy重複了很多,我想知道什麼是最好的方式來處理它?
try:
#do some database query
db_session.commit()
except: #some exception handling
db_session.rollback()
這是從我的工作代碼,一個會話註冊表包裝的方法是正確的。
它這樣使用:
# dblink is an object that knows how to connect to the database
with dblink.CommittingSession() as session:
session.add(...)
# do anything else
# at this point, session.commit() has been called
或者:
try:
with dblink.CommittingSession() as session:
session.add(...)
except ...:
# at this point, session.rollback has been called
log.error('We failed!')
實施:
from contextlib import contextmanager
class DbLink(object):
"""This class knows how to connect to the database."""
# ...
# Basically we wrap a sqlalchemy.orm.sessionmaker value here, in session_registry.
# You might want to create sessions differently.
@contextmanager
def CommittingSession(self, **kwargs):
"""Creates a session, commits at the end, rolls back on exception, removes.
Args:
**kwargs: optional; supplied to session_registry while asking
to construct a session (mostly for testing).
Yields:
a session object. The session will .commit() when a `with SimpleSession()`
statement terminates normally, or .rollback() on an exception.
"""
try:
session = self.session_registry(**kwargs) # this gives us a session
# transaction has already begun here, so no explicit .begin()
yield session
except:
session.rollback()
raise
else:
session.commit()
finally:
# Note: close() unbinds model objects, but keeps the DB connection.
session.close()
self.session_registry.remove()
您可以設計一個函數來管理錯誤句柄,您應該評估它們並考慮是否需要性能優化。
def commit_or_rollback(my_session, do_something, error_type):
try:
do_something(my_session)
my_session.commit()
return True
except error_type as err:
my_session.rollback()
print(err)
return False
def do_something(my_session):
# do something
commit_result = commit_or_rollback(my_session, do_something, NoResultFound)
要小心會話控制和性能。這種方法可以保持代碼清晰。