Как передать динамическое имя базы данных декоратору? - PullRequest
3 голосов
/ 08 февраля 2012

Django имеет функцию декоратора под названием @transaction.commit_manually. Я пытаюсь передать параметр этому декоратору, (using=db). db зависит от используемой базы данных в зависимости от бизнес-правил. Как лучше всего передать текущую базу данных этому декоратору? Я попытался использовать внутреннюю функцию, таким образом:

def func(db):
    stuff = _business logic_

    @transaction.commit_manually(using=db)
    def do_transaction(stuff):
        try:
            stuff.save(using=db)
        except:
            transaction.rollback()
        else:
            transaction.commit()

    do_transaction()

Однако это не удалось. Ошибка, обнаруженная с помощью pdb, заключается в том, что внутренний блок «Не находится под управлением транзакциями». Как мне преодолеть эту проблему?

Traceback от pdb:

-> success = transactional_registration()
  /usr/local/lib/python2.7/dist-packages/django/db/transaction.py(338)_commit_manually()
-> return func(*args, **kw)
> /home/syrion/dev/registration.py(59)transactional_registration()
-> transaction.rollback()
  /usr/local/lib/python2.7/dist-packages/django/db/transaction.py(210)rollback()
-> set_clean(using=using)
  /usr/local/lib/python2.7/dist-packages/django/db/transaction.py(125)set_clean()
-> raise TransactionManagementError("This code isn't under transaction management"

Редактировать : Я исправил свою проблему. Решение для внутренней функции работает правильно, но мне нужно было вызывать rollback() и commit() с параметром using, т.е. transaction.commit(using=db). Я нахожу это не интуитивным, но ...

1 Ответ

1 голос
/ 15 июня 2012

Я использую это довольно часто в своем коде, так как большое внимание уделяю ORM.Поскольку я не большой поклонник синтаксиса декораторов, я использую оператор with.

def do_transaction(stuff, db):
    with transaction.commit_manually(using=db)
        try:
            stuff.save(using=db)
        except:
            transaction.rollback()
        else:
            transaction.commit(using=db)

Это должно работать.Не уверен, что вам понадобится (using=db) в вашем transaction.rollback().Я уверен, что вы можете исследовать это.Но вам нужно (using=db) в transaction.commit(using=db).

...