Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a dynamic database name to a decorator?

Django has a decorator function called @transaction.commit_manually. I am attempting to pass a parameter to this decorator, (using=db). db varies depending on which database is being used, based on business rules. What is the best way to pass the current database to this decorator? I tried to use an inner function, thus:

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()

However, this fails. The error I discovered with pdb is that the inner block is "Not under transaction management." How do I overcome this problem?

Traceback from 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"

Edit: I fixed my own problem. The internal function solution works correctly, but I needed to be calling rollback() and commit() with a using parameter, i.e. transaction.commit(using=db), as well. I find that unintuitive, but...

like image 786
asthasr Avatar asked Nov 21 '25 18:11

asthasr


1 Answers

I use this quite often in my code since I put a lot of stress on the ORM. Since I'm not a big fan of decorator syntax I use the with statement.

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

This should work. Not sure if you're going to need (using=db) in your transaction.rollback(), though. I'm sure you can do the research on that. But you do need (using=db) in transaction.commit(using=db).

like image 147
notbad.jpeg Avatar answered Nov 23 '25 08:11

notbad.jpeg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!