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