Skip to content

Instantly share code, notes, and snippets.

@pongo
Last active August 18, 2022 08:19
Show Gist options
  • Select an option

  • Save pongo/2b967a2f3bc10a22c7ee73faba03c42f to your computer and use it in GitHub Desktop.

Select an option

Save pongo/2b967a2f3bc10a22c7ee73faba03c42f to your computer and use it in GitHub Desktop.
Обрабатывать ошибки бд

Список функций для повтора

Скорее всего эту будем использовать:

Другие библиотеки:

Еще:

Работа с бд

Примерно как здесь:

# session.begin()  # больше не нужно вызывать .begin()
# there is no need to explcitly begin transactions when using modern Session programming patterns
try:
    item1 = session.query(Item).get(1)
    item2 = session.query(Item).get(2)
    item1.foo = 'bar'
    item2.bar = 'foo'
    session.commit()
except:
    session.rollback()
    raise

Еще советики отсюда

  • Use read-only database sessions if you know you do not need to modify the database and you need weaker transaction guarantees e.g. for displaying the total balance.
  • Never do external actions, like sending emails, inside managed_transaction. If the database transaction is replayed, the code is run twice and you end up sending the same email twice.
  • Managed transaction section should be as small and fast as possible.
  • Avoid long-running transactions by splitting up big transaction to smaller worker batches.

Что делать

Ищем все db.commit и переносим их в отдельную функцию с повторяющим декоратором. А внутри функции делать try: код, db.commit(), except: db.rollback()

Мб убрать expire_on_commit=False?

def retry(exceptions=Exception, tries=4, delay=3, backoff=2, logger=None):
"""
Retry calling the decorated function using an exponential backoff.
Args:
exceptions: The exception to check. may be a tuple of
exceptions to check.
tries: Number of times to try (not retry) before giving up.
delay: Initial delay between retries in seconds.
backoff: Backoff multiplier (e.g. value of 2 will double the delay
each retry).
logger: Logger to use. If None, print.
See:
https://www.calazan.com/retry-decorator-for-python-3/
"""
def deco_retry(f):
@wraps(f)
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries > 1:
try:
return f(*args, **kwargs)
except exceptions as e:
msg = f'{e}, Retrying in {mdelay} seconds...'
if logger:
logger.warning(msg)
else:
print(msg)
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
return f(*args, **kwargs)
return f_retry # true decorator
return deco_retry
@pongo

pongo commented Dec 31, 2017

Copy link
Copy Markdown
Author

В итоге пришел к решению contextmanager отсюда http://docs.sqlalchemy.org/en/latest/orm/session_basics.html и еще

session_factory = sessionmaker(bind=engine, expire_on_commit=False)
Session = scoped_session(session_factory)

А db создается каждый раз в том contextmanager

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment