AttributeError: 'Mapper' object has no attribute '_Mapper__props_init'

Issue #613 resolved
Former user created an issue

We are building an internet application based on SQL Alchemy. Since this is a kind of low traffic backoffice, we create a new connection on every request (sqlalchemy.create_engine(...)).

We are using PyMSSQL under linux and PyODBC under windows. We don't feel that the problem comes from the SQL backend.

When we stress the site, some strange problems raise. The connection is always well established (create_engine always returns us a successful result) but the first request (a simple querry / select) raises an exception :

...
 Module sqlalchemy.orm.session, line 281, in query
 Module sqlalchemy.orm.mapper, line 1846, in class_mapper
 Module sqlalchemy.orm.mapper, line 321, in compile
 Module sqlalchemy.orm.mapper, line 340, in _compile_all
AttributeError: 'Mapper' object has no attribute '_Mapper__props_init'

This exception appears randomly. We are using Zope (without z3c.sqlalchemy) with 4 threads.

We feel this problem is a concurrency problem since the more the threads we add, the more often the exception raises. When we only use 1 thread, there is no more exception at all.

Some coworkers are also using SQL Alchemy, with Zope too, and with z3c.sqlalchemy. This last product enables one connexion per Zope thread. Times to times, they experiment this exception too.

We also experiment another exception, with the same symptoms:

...
 Module sqlalchemy.orm.query, line 137, in get_by
 Module sqlalchemy.orm.query, line 325, in select_whereclause
 Module sqlalchemy.orm.query, line 1040, in compile
 Module sqlalchemy.orm.interfaces, line 160, in setup
 Module sqlalchemy.orm.interfaces, line 143, in _get_context_strategy
AttributeError: 'PropertyLoader' object has no attribute 'strategy'

Comments (4)

  1. Mike Bayer repo owner

    the first stack trace occurs during the compilation stage of mappers, which is synchronized with a mutex, which was added somewhere in the middle of the 0.3 series. are you using the latest release ? once the mapper fails to compile, the entire application is in an invalid state so the subsequent exceptions are meaningless.

    if youd like to override the operation yourself, do this during your initialization:

    import threading
    lock = thread.Lock()
    lock.acquire()
    try:
        compile_mappers()
    finally:
        lock.release()
    

    additionally, it is best if all mappers are created before any Query is issued, which would ensure that only one compilation phase occurs.

  2. Mike Bayer repo owner

    in fact thats probably what it is, theres no mutex on the constructor of Mapper, which changes the collection of mappers that compile() is processing. will create a fix soon, in the meantime fully create all mappers before any query or flush() is issued.

    (low priority was an accident)

  3. Log in to comment