Hello, I am having problems with the new Singleton DAL feature and a web-app that I had already working correctly with web2py.
Although the web-app itself runs ok (I can navigate the browser to it, and the app runs without issues when used from the browser), it crashes when I run unit-tests on it (by means of web2py.test-runner). More specifically, each test crashes with the following stack trace: ------------- Traceback (most recent call last): File "/stuff/web2py/gluon/restricted.py", line 209, in restricted exec ccode in environment File "/stuff/web2py/applications/me_app/models/00_app_config.py", line 61, in <module> initialize = Initialization(settings, T, request, response, session, cache) File "/stuff/web2py/applications/me_app/modules/model_logic/config.py", line 53, in __init__ (db, archival_db, scheduler_db) = self.__init_db() File "/stuff/web2py/applications/me_app/modules/model_logic/config.py", line 88, in __init_db check_reserved=check_reserved) File "/stuff/web2py/gluon/dal.py", line 6595, in __new__ raise RuntimeError, 'Cannot duplicate a Singleton' RuntimeError: Cannot duplicate a Singleton ------------- The statement that makes this crash is: ------------- db = DAL( settings.db_uri if not request.is_testing else 'sqlite:memory:', migrate_enabled=settings.migrate or request.is_testing, lazy_tables=True, #bigint_id=True, # TODO check_reserved=check_reserved) ------------- I also create other databases after db that, in testing mode, also point to 'sqlite:memory'. If I comment those other databases out, the first test passes ok, but the other ones still crash. If I try to comment the lines that originate this error (http://code.google.com/p/web2py/source/browse/gluon/dal.py#6594 and http://code.google.com/p/web2py/source/browse/gluon/dal.py#6595), then I get an error when creating the first table in my db: ------------- Traceback (most recent call last): File "/stuff/web2py/gluon/restricted.py", line 209, in restricted exec ccode in environment File "/stuff/web2py/applications/me_app/models/08_domain.py", line 14, in <module> current.domain = domain = domain_model.define_domain() File "/stuff/web2py/applications/me_app/modules/model_logic/domain_model.py", line 334, in define_domain domain=domain) File "/stuff/web2py/applications/me_app/modules/model_logic/domain_model.py", line 665, in __define_core on_define=init_domain__country, File "/stuff/web2py/gluon/dal.py", line 7034, in define_table raise SyntaxError, 'invalid table name: %s' % tablename SyntaxError: invalid table name: country ------------- which appears to be the same error message that has been reported by others (https://groups.google.com/d/msg/web2py-developers/CWxEhcWxiGM/-Aw_fhQQY4EJ). When I revert to r4184, everything runs peachy. Looking at the code for DAL, I am led to believe that this may have something to do with threading. Is there any way to disable the Singleton DAL feature selectively (at least for unit-testing, which does not use threading in the same manner as web containers do)? Best regards, JS On Tuesday, October 2, 2012 3:32:16 AM UTC+1, Massimo Di Pierro wrote: > > There is a big change in DAL. > > a = DAL(uri) > b = DAL(uri) > > now "a is b" because DAL is a singleton (almost). It is a thread local > singleton as long a uri is specified. > What does this mean in practice? > > It means that unless you have lazy virtual fields, Row and Rows objects > can be serialized (pickled), properly cached, and stored in session. > For example: > > session.rows = session.rows or db(db.mytable).select() > > and you can still do: > > session.rows.first().update_record(....) > > has many practical implications in the way you program and there is even > more we could do. In the future we may be able to serialize every DAL > expression. > > This is a big change in the source and the internal logic is complex. > It may have some unforeseen side effects. > PLEASE TEST THAT TRUNK DOES NOT BREAK YOUR CODE before this makes it into > stable. > > massimo > > > > > > --