2010-08-31 10 views
3

Я хотел бы управлять деятельностью пользователя OpenERP, установив модуль аудита.
После создания некоторых правил (определить, какой пользователь, какой объект и какой вид деятельности (создать, обновить ..) будет отслеживаться). Я обновляю продукт, чтобы увидеть, как он работает.
Когда я попытался обновить продукт, я получил системную ошибку. Увидев журнал, я получаю
[2010-08-31 12: 53: 35,042] Курсор не закрыт явно
[2010-08-31 12: 53: 35,043] Курсор был создан в/home/pilgrim/working/источники/аддоны/AuditTrail/audittrail.py: 204

Здесь линия, которая вызывает ошибку
кр = pooler.get_db (дБ) .cursor()
Глядя на sql_db.py, я получаю свой комментарийИзбегайте ошибки OpenITP audittrail

def __del__(self): 
    if not self.__closed: 
     # Oops. 'self' has not been closed explicitly. 
     # The cursor will be deleted by the garbage collector, 
     # but the database connection is not put back into the connection 
     # pool, preventing some operation on the database like dropping it. 
     # This can also lead to a server overload. 
     msg = "Cursor not closed explicitly\n" \ 
       "Cursor was created at %s:%s" % self.__caller 
     log(msg, netsvc.LOG_WARNING) 
     self.close() 

Поскольку я новичок в Python, я не знаю, как преодолеть эту проблему?
Любой намек на это?
Thank

+0

Внимание будет поднят только в том случае, когда вы открыли курсор явно себя и забыл закрыть его после выполнения вашей логики, вам нужно вызвать cr.close(), прежде чем cr выйдет из его области. ... – shahjapan

ответ

4

t будет важным, чтобы увидеть исходный код, чтобы понять, что происходит. Но из того, что вы опубликовали, похоже, что предыдущий курсор не был явно закрыт.

cr = sqldb.db_connect(dbname).cursor() 
......... 
cr.close() 
cr = None 

Я хотел бы предложить вам взломать audittrail.py найти где-либо вы создаете курсор и где когда-либо закрыть их. Типичная проблема возникает при некорректной обработке исключений, что приводит к переходу кода на нормальное закрытие.

Попробуйте помещать попытку, кроме и, наконец, предложения вокруг сомнительной операции курсора. Это поможет вам обойти проблему.

1

Можете ли вы запустить OpenERP в отладчике, таком как PyDev plug in для Eclipse? Я считаю, что это самый эффективный способ отслеживания проблем. Я не использовал модуль аудита, но я быстро взглянул на source code, и кажется, что курсор открывается в начале log_fct(). (Я бы ожидал, чтобы сообщить линию 207, какую версию вы используете?) Вот что я думаю, что соответствующий код:

def log_fct(self, db, uid, passwd, object, method, fct_src, *args): 
    logged_uids = [] 
    pool = pooler.get_pool(db) 
    cr = pooler.get_db(db).cursor() # line 207 in version 5.0.12 

    # ... 

    if method in ('create'): 

     # ... 

     cr.close() 
     return res_id 

    # ... 

    cr.close() 

Похоже, есть несколько операторов возврата в методе, но каждый из них, кажется, сначала позвонить cr.close(), поэтому я не вижу никаких очевидных проблем. Попробуйте запустить его в отладчике с точкой останова в этом методе. Если это невозможно, то вы можете попробовать писать в журнал с чем-то вроде этого:

logger = netsvc.Logger() 
    logger.notifyChannel('audittrail', netsvc.LOG_INFO, 'something happened') 

Update: Вы отметили, что это происходит при большой нагрузке. Возможно, исключение выбрасывается, и курсор не закрывается. Вы можете использовать try ... finallystatement, чтобы убедиться, что курсор всегда закрыт. Ниже приведен пример описанного выше примера:

def log_fct(self, db, uid, passwd, object, method, fct_src, *args): 
    logged_uids = [] 
    pool = pooler.get_pool(db) 
    cr = pooler.get_db(db).cursor() # line 207 in version 5.0.12 
    try: 

     # ... 

     if method in ('create'): 

      # ... 

      return res_id 

     # ... 

    finally: 
     cr.close() 
+0

Я быстро просмотрел исходный код и не видел никаких очевидных проблем. У нас есть проблема в производственной среде, где многие пользователи делают много вещей, и эта проблема приводит к отключению связи. Я должен симулировать стресс-тесты, чтобы понять, как это работает. Примечание: Я использую Pydev, но ничего не нашел. Спасибо за ваш ответ. – Iapilgrim

+0

Добро пожаловать, @lapilgrim. Я добавил еще одно предложение экспериментировать с попыткой ... наконец. –

2

Думаю, я нахожу ответ. Смотрите пример

def a(): 
    try: 
    print 'before return ' 
    return 1 
    finally: 
    print 'in finally' 

вызов а()

before return 
in finally 
1 

Это нормально. ОК. Попробуйте другой пример (код экстракт из audittrail.py)

def do_something_with_db(db): 
    // open cusror again 
    cr = db.cursor() 
    // do somethign 
    // close cursor internally 
    cr.close() 
def execute(db) 
    // 1, open connection and open cursor 
    cr = db.cursor 
    try: 
     //2, do something with db, seeing that this method will open cursor again 
     return do_something_with_db(db) 
    finally: 
     cr.close() 

Видя, что реализация do_something_with_db пытается открыть курсор (можно назвать соединение), но ток один не явно закрыт. Так что решение очень простое: Пропускает ток кра вокруг

Before 
**do_something_with_db(db)** 
after 
**do_something_with_db(cr)** 

Теперь ошибка ушла.

@Don Kirkby: Да, мы должны экспериментировать с Try ... наконец