2012-02-08 146 views
3

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發現的錯誤是內部塊「不在事務管理下」。我如何克服這個問題?

回溯從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(),即使用transaction.commit(using=db)。我發現這不直觀,但...

+0

你可以在transaction.rollback()之後添加一個raise,併發布stacktrace + full錯誤? – 2012-02-08 19:56:01

+0

你爲什麼如此複雜?爲什麼func不是可調用的對象? – 2012-02-08 19:57:02

+0

'func'是一個對象的可調用方法。如果我自己裝飾'func',數據庫超出範圍。 – syrion 2012-02-08 20:09:55

回答

1

我在我的代碼中經常使用它,因爲我在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) 

這應該有效。不過,不知道您是否需要transaction.rollback()中的(using=db)。我相信你可以對此進行研究。但你需要(using=db)transaction.commit(using=db)

相關問題