Think the combination of persistant logger object and SQLite threading 
issues makes this too hard (couldn't get it working with commit() either)- 
I'll look for a simpler solution.

(PS- For non web2py-DAL sqlite logging, I stumbled upon a thread safe class 
I built a while back- still works, in case anyone's interested: 
SQLiteHandler <https://gist.github.com/2662203#file_sqlite_handler.py>)

On Friday, May 11, 2012 6:07:30 PM UTC-4, Massimo Di Pierro wrote:
>
> After
>
> self.log_db.log.insert(**args)
>
> you need
>
> self.log_db.commit()
>
> every http request, the models, are executed, DAL(...) connects you to the 
> db (or recycles a connection from the pool), then when the action is done, 
> it automatically commits or rollsback, then web2py closes the connection.
>
> If you import a module, Python caches the module. A db connection defined 
> in the module, lives as long as the module lives. A db connection defined 
> in a model lives only as long as the http request lives. If you pass one to 
> the other you run into trouble.
>
> One more complication is that if you use sqlite, if one process/thread 
> opens the file and tries write into it, the file gets locked.
>
>
>
> On Friday, 11 May 2012 15:40:39 UTC-5, Yarin wrote:
>>
>> Massimo- see revised - this is one model file and now I'm defining the db 
>> in the constructor, but I get the "Cannot operate on a closed database" 
>> error immediately. 
>>
>>
>> import logging
>> import logging.handlers
>>
>> class AppHandler(logging.Handler): # Inherit from logging.Handler
>>     def __init__(self):
>>          logging.Handler.__init__(self)
>>  
>>          self.log_db = DAL('sqlite://log.sqlite')
>>          self.log_db.define_table('log',
>>              Field('loggername', 'string'),
>>              Field('srclineno', 'string'), 
>>              Field('func', 'string'), 
>>              Field('level', 'string'), 
>>              Field('msg', 'string'), 
>>              Field('type', 'string')
>>              )
>>
>>     def emit(self, record):
>>  
>>          args = {}
>>          args['loggername'] = record.name  
>>          args['srclineno'] = record.lineno
>>          args['func'] = record.funcName
>>          args['level'] = record.levelname
>>          args['msg'] = record.msg
>>          try:
>>              args['type'] = record.args[0]
>>          except:
>>              args['type'] = None
>>  
>>          self.log_db.log.insert(**args)
>>
>> logger = logging.getLogger("web2py.app.myapp")
>> logger.setLevel(logging.DEBUG)
>> logger.addHandler(AppHandler())
>> logger.debug('test log')
>>
>>
>>
>>
>> Are you saying I need to make a connection and commit manually? How come 
>> this isn't required in the normal db.py file's db definition- there we just 
>> define it and go?
>>
>> On Friday, May 11, 2012 4:19:22 PM UTC-4, Massimo Di Pierro wrote:
>>>
>>> Is this one or two files?
>>>
>>> If the model is passing db to the logger then the db is closed when the 
>>> first request responds.
>>> The logger must make its own connection to the db and commit
>>>
>>> On Friday, 11 May 2012 14:28:22 UTC-5, Yarin wrote:
>>>>
>>>> Here is my complete model code for a sqlite logging handler. This works 
>>>> the first time the program is run, and after that I get an error:
>>>>
>>>> <class 'sqlite3.ProgrammingError'> Cannot operate on a closed database.
>>>>
>>>>
>>>> *model mylogging.py:*
>>>>
>>>> import logging
>>>> import logging.handlers
>>>>
>>>>
>>>> class AppHandler(logging.Handler): # Inherit from logging.Handler
>>>>     def __init__(self):
>>>>  logging.Handler.__init__(self)
>>>>  
>>>>  self._db = db
>>>>
>>>>
>>>>     def emit(self, record):
>>>>  
>>>>  args = {}
>>>>  args['loggername'] = record.name
>>>>  args['srclineno'] = record.lineno
>>>>  args['func'] = record.funcName
>>>>  args['level'] = record.levelname
>>>>  args['msg'] = record.msg
>>>>  try:
>>>>  args['type'] = record.args[0]
>>>>  except:
>>>>  args['type'] = None
>>>>  
>>>>  self._db.log.insert(**args)
>>>>
>>>>
>>>>
>>>>
>>>> log_db = DAL('sqlite://log.sqlite')
>>>> log_db.define_table('log',
>>>>  
>>>>  Field('loggername', 'string'), #unique=True
>>>>  Field('srclineno', 'string'), 
>>>>  Field('func', 'string'), 
>>>>  Field('level', 'string'), 
>>>>  Field('msg', 'string'), 
>>>>  Field('type', 'string'),
>>>>  )
>>>>
>>>>
>>>> import logging
>>>> logger = logging.getLogger("web2py.app.myapp")
>>>> logger.setLevel(logging.DEBUG)
>>>>
>>>>
>>>> logger.addHandler(AppHandler(log_db))
>>>> logger.debug('test log')
>>>>
>>>>
>>>>
>>>> I don't understand how I'm causing this, as all as im doing is creating 
>>>> a second db instance and inserting using web2py DAL methods?
>>>>
>>>>

Reply via email to