[web2py] Re: Modules: how to access db
I just ran into this problem too and decided to solve it like this: in my controller: from gluon import current a_module = local_import('a_module') def a_function(): a_module.something_cool(auth, current) The db connection is available as auth.db, and the request, session, and response are in current. On Thursday, February 9, 2012 11:31:08 PM UTC+11, spyker wrote: I am not ready with this project to try out Bruno's way of setting up a database using modules and not models. But I want to be able to do something like this in a module: def number_or_records(table): count = db(db[table]).count() -- Because experiencing your loyal love is better than life itself, my lips will praise you. (Psalm 63:3)
Re: [web2py] Re: Modules: how to access db
On 9 February 2012 18:14, Bruno Rocha rochacbr...@gmail.com wrote: I dont know exactly how it works, but I had problems serializing db in to current, so Massimo said to always pass it explicitly to classes ad functions, I remember that SQLITE worked, but not Postgres. Anthony's advice to me earlier in this thread is working with PostgreSQL: In db.py: from gluon import current current.db = db and in the module: from gluon import * def regte_verwysing(regte, tabel, veld): db = current.db lys = db(db[tabel].article == regte).select(db[tabel][veld]) verwysings = [x[veld] for x in lys] return verwysings Regards Johann -- Because experiencing your loyal love is better than life itself, my lips will praise you. (Psalm 63:3)
Re: [web2py] Re: Modules: how to access db
other ways to do it without using current. in the module (ex. tools.py): def regte_verwysing(regte, tabel, veld, db): lys = db(db[tabel].article == regte).select(db[tabel][veld]) verwysings = [x[veld] for x in lys] return verwysings in the model (ex. db.py): import tools.py def regte_verwysing(regte, tabel, veld): return tools.regte_verwysing(regte, tabel, veld, db) If you like closures. in the module (ex. tools.py): def regte_verwysing(db): def f(regte, tabel, veld): lys = db(db[tabel].article == regte).select(db[tabel][veld]) verwysings = [x[veld] for x in lys] return verwysings return f in the model (ex. db.py): import tools.py regte_verwysing = tools.regte_verwysing(db) #- returns a callable with args (regte, tabel, veld) you can then call regte_verwysing(regte, tabel, veld) in your code mic 2012/2/10 Johann Spies johann.sp...@gmail.com: On 9 February 2012 18:14, Bruno Rocha rochacbr...@gmail.com wrote: I dont know exactly how it works, but I had problems serializing db in to current, so Massimo said to always pass it explicitly to classes ad functions, I remember that SQLITE worked, but not Postgres. Anthony's advice to me earlier in this thread is working with PostgreSQL: In db.py: from gluon import current current.db = db and in the module: from gluon import * def regte_verwysing(regte, tabel, veld): db = current.db lys = db(db[tabel].article == regte).select(db[tabel][veld]) verwysings = [x[veld] for x in lys] return verwysings Regards Johann -- Because experiencing your loyal love is better than life itself, my lips will praise you. (Psalm 63:3)
[web2py] Re: Modules: how to access db
Instead of using gluon, I pass it while importing the module. For example, if my module is commons, then in my controller: import commons commons.db = db commons.request = request commons.session = session Now db , request and session should now be available in the module...
[web2py] Re: Modules: how to access db
This solution will lead to a race condition. Do not use it! If you have multiple threads, they might update your commons at the same time and you'll get request from one session, and session from another, and db from a third. current is a thread-local thing, guaranteed not to be touched by any other part - use current, not common (or whatever your own module is called)
Re: [web2py] Re: Modules: how to access db
Thanks for that! I've never tested it in a multi-threaded environment. On Sat, Feb 11, 2012 at 4:41 AM, nick name i.like.privacy@gmail.comwrote: This solution will lead to a race condition. Do not use it! If you have multiple threads, they might update your commons at the same time and you'll get request from one session, and session from another, and db from a third. current is a thread-local thing, guaranteed not to be touched by any other part - use current, not common (or whatever your own module is called) -- Sathvik Ponangi
[web2py] Re: Modules: how to access db
Sorry the message was sent before I have finished typing. How do I get the same environment available in the module as in the controller? Regards Johann -- Because experiencing your loyal love is better than life itself, my lips will praise you. (Psalm 63:3)
[web2py] Re: Modules: how to access db
from gluon import * This should give you the current object which has these: current.request current.response current.cache You must initialize your modules with a db instance though. So I usually do this: class MyModule(object): def __init__(self, db, ...)
Re: [web2py] Re: Modules: how to access db
Thanks Ross. On 9 February 2012 14:39, Ross Peoples ross.peop...@gmail.com wrote: from gluon import * This should give you the current object which has these: current.request current.response current.cache You must initialize your modules with a db instance though. So I usually do this: class MyModule(object): def __init__(self, db, ...) I do not understand this properly. After explicitly importing 'current' in the controller, I made some progress. But why is the class definition necessary and how does it initialise db when db is not available in the module? Regards Johann -- Because experiencing your loyal love is better than life itself, my lips will praise you. (Psalm 63:3)
Re: [web2py] Re: Modules: how to access db
I do not understand this properly. After explicitly importing 'current' in the controller, I made some progress. But why is the class definition necessary and how does it initialise db when db is not available in the module? You don't necessarily need a class. The point is just that you need to pass in the db instance, either via an __init__ method of a class, or simply as an argument to your function. In your case: def number_of_records(db, table): And when you call that function, pass in your db object as the first argument. Another option is to add the db object to current -- for example, in the db.py model file: from gluon import current current.db = db Then when you import current in your module, you can refer to current.db. Anthony
Re: [web2py] Re: Modules: how to access db
On 9 February 2012 15:45, Anthony abasta...@gmail.com wrote: I do not understand this properly. After explicitly importing 'current' in the controller, I made some progress. But why is the class definition necessary and how does it initialise db when db is not available in the module? You don't necessarily need a class. The point is just that you need to pass in the db instance, either via an __init__ method of a class, or simply as an argument to your function. In your case: def number_of_records(db, table): And when you call that function, pass in your db object as the first argument. Another option is to add the db object to current -- for example, in the db.py model file: from gluon import current current.db = db Then when you import current in your module, you can refer to current.db. Thanks Anthony. That clears up a few things for me. Regards Johann -- Because experiencing your loyal love is better than life itself, my lips will praise you. (Psalm 63:3)
Re: [web2py] Re: Modules: how to access db
On Thu, Feb 9, 2012 at 11:45 AM, Anthony abasta...@gmail.com wrote: from gluon import current current.db = db I dont think that adding db to current will work properly, it can work in SQLITE, but for sure will raise problems with another databases. I realized that db needs to be instantiated inside a module or passed explicitly as an arg, it is not possible to serialize it in to current. It works in the first request, but not for the subsequents. Another advice is that you never have to assign variables to current outside functions and methods Example. *Module.py* from gluon import current request = current.request def myfunction(db): if request.args... # HERE BE THE DRAGONS! To work you need to do *Module.py* from gluon import current def myfunction(db): request = current.request if request.args # IT WORKS It happens because if you assign outside the function, it will be evaluated only at the first request, and for the subsequents, the request object will always be the same. -- Bruno Rocha [http://rochacbruno.com.br]
[web2py] Re: Modules: how to access db
With the last version, you can do this : from gluon import current dba = current.globalenv['db']
Re: [web2py] Re: Modules: how to access db
Now that is a lot nicer then passing in the db to every module class. Does this only work with trunk? Or the latest stable release? On Thu, Feb 9, 2012 at 7:30 AM, omicron jacques.bouss...@gmail.com wrote: With the last version, you can do this : from gluon import current dba = current.globalenv['db'] -- -- Regards, Bruce Wade http://ca.linkedin.com/in/brucelwade http://www.wadecybertech.com http://www.warplydesigned.com http://www.fitnessfriendsfinder.com
[web2py] Re: Modules: how to access db
On Thursday, February 9, 2012 10:30:12 AM UTC-5, omicron wrote: With the last version, you can do this : from gluon import current dba = current.globalenv['db'] I wonder why current.globalenv['db'] would work but current.db would not.
[web2py] Re: Modules: how to access db
based on advice on the group long ago i am using a pattern like this: in db.py: current.myapp = Storage() current.myapp.db = db #after db is inited then in my module refrencing db as: current.myapp.db i'm using this on GAE and it has been working like a champ. the key is to add the just defined version of the db variable to current on each request, and not cache it as a static variable. remember that db changes on each request (new connection from the pool, different default and requests for table fields etc), so you can't keep db a static module variable or a static global variable and have it work for more then 1 request.
[web2py] Re: Modules: how to access db
based on advice on the group long ago i am using a pattern like this: in db.py: current.myapp = Storage() current.myapp.db = db #after db is inited If that works, then current.db should work as well, no (I understand the idea behind putting everything app-specific in current.myapp to avoid possible future namespace conflicts, I'm just saying in theory current.db should work, shouldn't it)? Anthony
Re: [web2py] Re: Modules: how to access db
I dont know exactly how it works, but I had problems serializing db in to current, so Massimo said to always pass it explicitly to classes ad functions, I remember that SQLITE worked, but not Postgres. -- Bruno Rocha [http://rochacbruno.com.br]