[Sqlalchemy-tickets] Issue #4169: Inconsistent Execution order for "mapper_configured" (zzzeek/sqla
Brought to you by:
zzzeek
From: Lukas S. <iss...@bi...> - 2018-01-22 21:32:40
|
New issue 4169: Inconsistent Execution order for "mapper_configured" https://bitbucket.org/zzzeek/sqlalchemy/issues/4169/inconsistent-execution-order-for Lukas Siemon: We have been getting random failures. I narrowed this down to non deterministic execution order. I've included a (somewhat) minimal test case below. The way the test case is currently set up it sometimes fails and other times it doesn't (might depend on compilation order?). If I comment the first `sleep(1)` the test always fails. If I comment the second `sleep(1)` the test never fails. We would expect the execution order to be consistent. ```python import unittest from time import sleep from sqlalchemy import Column, Integer, event, literal, func, select from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import mapper, column_property from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = ("sqlite://") app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) Base = declarative_base() class Venue(db.Model): __tablename__ = 'venue' id = Column(Integer, primary_key=True, nullable=False) class Offer(db.Model): __tablename__ = 'offer' id = Column(Integer, primary_key=True, nullable=False) @event.listens_for(mapper, "mapper_configured") def mapper_listener(mapper_, cls): if issubclass(cls, Venue): sleep(1) cls.info = column_property( select([ func.SUM(Offer.info) ]).where( Offer.id <= Venue.id ).as_scalar() ) @event.listens_for(mapper, "mapper_configured") def mapper_listener(mapper_, cls): if issubclass(cls, Offer): sleep(1) cls.info = column_property(cls.id + literal("1")) db.drop_all() db.create_all() class TestExecutionOrder(unittest.TestCase): def test_execution_order(self): db.session.add(Venue()) db.session.add(Offer()) db.session.commit() venue = Venue.query.one() print venue.info ``` Stacktrace when test fails: ```sh Traceback (most recent call last): File "/usr/lib/python2.7/unittest/case.py", line 329, in run testMethod() File ".../test.py", line 53, in test_execution_order db.session.add(Venue()) File "<string>", line 2, in __init__ File ".../env/local/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", line 347, in _new_state_if_none state = self._state_constructor(instance, self) File ".../env/local/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 767, in __get__ obj.__dict__[self.__name__] = result = self.fget(obj) File ".../env/local/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", line 177, in _state_constructor self.dispatch.first_init(self, self.class_) File ".../env/local/lib/python2.7/site-packages/sqlalchemy/event/attr.py", line 256, in __call__ fn(*args, **kw) File ".../env/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 3123, in _event_on_first_init configure_mappers() File ".../env/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 3016, in configure_mappers mapper, mapper.class_) File ".../env/local/lib/python2.7/site-packages/sqlalchemy/event/attr.py", line 218, in __call__ fn(*args, **kw) File ".../env/local/lib/python2.7/site-packages/sqlalchemy/orm/events.py", line 621, in wrap fn(*arg, **kw) File ".../test.py", line 33, in mapper_listener func.SUM(Offer.info) AttributeError: type object 'Offer' has no attribute 'info' ``` Running latest PostgreSQL 9.6 |