All these methods work great. db.reconnect() is experimental and I cannot 
promise it has no memory leaks.

On Tuesday, 11 December 2012 05:14:27 UTC-6, simon wrote:
>
> OK I did not realise that if different threads import a module then it is 
> only imported once and the globals are shared between threads.
>
> I have a number of functions in the module and they all use db 
> extensively. If I use db=DAL() or db.reconnect() at each request then the 
> db is not available to each function in the module. I think my options are:
>        1) Pass db as a parameter to each function in the module
>        2) Turn the module into a class and use self.db everywhere
>        3) Put the db in current and have db=current.db at the top of each 
> function in the module
>
> Is there a better way e.g. can I somehow force each thread/request to use 
> their own version of a module with their own version of a db connection; 
> but make the db connection available to all functions within the module.
>
>
> On Tuesday, 11 December 2012 00:24:40 UTC, Massimo Di Pierro wrote:
>>
>> You should now make web global. Imagine two requests arrive more or less 
>> at the time time. Both call connect? Now you have two threads using the 
>> same global web object. You are back to the previous problem. This breaks 
>> connection pooling, thread safety, etc.
>>
>> You either call db = DAL() at each request and db is a local variable of 
>> the request (which you call web) or you call db once in your model and use 
>> db.reconnect() to duplicate the connection in the thread that is using it 
>> (experimental).
>>
>>
>> On Monday, 10 December 2012 10:49:40 UTC-6, simon wrote:
>>>
>>> OK. I think I have done something similar to your suggestion. It seems 
>>> to work but not sure about memory leaks. Also I note there is no web2py 
>>> method to close a database connection.
>>>
>>> I want to put all the code interfacing to a 3rd party system in a single 
>>> file. In that way if I change to a different 3rd party package I just need 
>>> to change the one file.
>>>
>>> MODULE:
>>>
>>> MODEL:
>>>     import ocart2
>>>     web=ocart2.connect()
>>>     rows=web(web.category.category_id>0).select()
>>>     log.info((web.tables, rows))
>>>
>>> MODULE:
>>> web=None
>>>
>>> def connect():
>>>     global web
>>>     web=DAL(webstring, pool_size=10, migrate=False, 
>>> migrate_enabled=False)
>>>     web.define_table('category',
>>>         Field('category_id', 'id', notnull=True, writable=False),
>>>         Field('parent_id', 'integer', default=0, notnull=True, 
>>> writable=False),
>>>         Field('status', 'integer', default=1),
>>>         Field('top', 'integer', notnull=True, writable=False))
>>>     return web
>>>
>>>
>>>
>>>
>>>
>>> On Monday, 10 December 2012 15:39:34 UTC, Massimo Di Pierro wrote:
>>>>
>>>> You cannot do this. The connection has to be stablished in the models 
>>>> and the tables have to be defined in the models as well.
>>>>
>>>> The issue is that a db connection only lives within a thread. Since 
>>>> web2py is multithreaded at every request you may get a different thread.
>>>>
>>>>  If is ok to do
>>>>
>>>> import ocart2
>>>> web=ocart2.web()
>>>> rows=web(web.category.category_id>0).select()
>>>> log.info((web.tables, rows))
>>>>
>>>> MODULE:
>>>> from gluon import *
>>>> from config import webstring
>>>> def web():
>>>>    db = DAL(webstring, pool_size=10, migrate=False, 
>>>> migrate_enabled=False)
>>>>    db.define_table('category',
>>>>      Field('category_id', 'id', notnull=True, writable=False),
>>>>      Field('parent_id', 'integer', default=0, notnull=True, 
>>>> writable=False),
>>>>      Field('status', 'integer', default=1),
>>>>      Field('top', 'integer', notnull=True, writable=False))
>>>>    return db
>>>>
>>>> You may also be able to do this:
>>>>
>>>> MODEL:
>>>>
>>>> import ocart2
>>>> web=ocart2.web
>>>> web.reconnect() # <<<
>>>> rows=web(web.category.category_id>0).select()
>>>> log.info((web.tables, rows))
>>>>
>>>> MODULE:
>>>> from gluon import *
>>>> from config import webstring
>>>> web=DAL(webstring, pool_size=10, migrate=False, migrate_enabled=False)
>>>> web.define_table('category',
>>>>     Field('category_id', 'id', notnull=True, writable=False),
>>>>     Field('parent_id', 'integer', default=0, notnull=True, 
>>>> writable=False),
>>>>     Field('status', 'integer', default=1),
>>>>     Field('top', 'integer', notnull=True, writable=False))
>>>>
>>>> Yet the reconnect() method is experimental and I am not sure it does 
>>>> not cause a memory leak. Yet you can help me test it.
>>>>
>>>> On Monday, 10 December 2012 04:13:43 UTC-6, simon wrote:
>>>>>
>>>>> In my model file I am importing a database definition from a module 
>>>>> file.
>>>>> This works correctly the first time after the server is started 
>>>>> showing the tablename and 11 rows in the table.
>>>>> However for the second and subsequent requests it shows a rows object 
>>>>> but 0 rows in the table.
>>>>> It works fine if I put the model definition code inline rather than 
>>>>> importing.
>>>>>
>>>>> [EDIT: I am fairly sure this used to work. Has something changed? Is 
>>>>> there a way to get this to work?]
>>>>>
>>>>> MODEL:
>>>>>
>>>>> import ocart2
>>>>> web=ocart2.web
>>>>> rows=web(web.category.category_id>0).select()
>>>>> log.info((web.tables, rows))
>>>>>
>>>>> MODULE:
>>>>> from gluon import *
>>>>> from config import webstring
>>>>> web=DAL(webstring, pool_size=10, migrate=False, migrate_enabled=False)
>>>>> web.define_table('category',
>>>>>     Field('category_id', 'id', notnull=True, writable=False),
>>>>>     Field('parent_id', 'integer', default=0, notnull=True, 
>>>>> writable=False),
>>>>>     Field('status', 'integer', default=1),
>>>>>     Field('top', 'integer', notnull=True, writable=False))
>>>>>
>>>>>

-- 



Reply via email to