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