Estoy trabajando para probar mi modelo de aplicación de matraz. Estoy usando mysql 5.7, sqlalchemy y pytest.
Dentro de mi modelo, tengo un mixin CRUD que utilicé para administrar la creación, actualización y eliminación. Cada vez que trato de acceder al objeto en Mixin antes de devolver el objeto a la función de prueba, SQLAlchemy se bloquea en db.drop_all en mi desmontaje. Cuando miro en mysql en PROCESSLIST, muestra 1 consulta de suspensión y 1 consulta esperando el bloqueo de metadatos de la tabla.
Puedo arreglar esto llamando a db.session.commit en el método de creación en el mixin antes de devolver el objeto. Sin embargo, si lo llamo en el desmontaje de prueba (o en la función de prueba principal), no funciona. Preferiría no agregar un compromiso adicional solo para que mis pruebas funcionen, ya que no se siente correcto. ¿Alguien sabe por qué sucede esto o tiene alguna solución sugerida?
modelos.py
class CRUDMixin(object): @classmethod def create(cls, **kwargs): instance = cls(**kwargs) saved_instance = instance.save() # do stuff with saved_instance (ie add to full text search engine) # db.drop_all in teardown works if add db.session.commit() here return saved_instance def save(self, commit=True): db.session.add(self) if commit: try: db.session.commit() except Exception: db.session.rollback() raise return self class User(CRUDMixin, db.model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50))concurso.py
@pytest.fixture(scope='session') def app(): app = create_app(TestConfig) ctx = app.app_context() ctx.push() yield app ctx.pop() @pytest.fixture(scope='session') def test_db(app): db.drop_all() db.create_all() # add test db information yield db db.session.remove() db.drop_all() # test hangs within drop all @pytest.fixture(scope='function') def db_session(test_db): connection = db.engine.connect() transaction = connection.begin() options = dict(bind=connection, binds={}) session = db.create_scoped_session(options) db.session = session yield db db.session.remove() # tables won't drop if I put db.session.commit before the remove call transaction.rollback() connection.close() # even though connection closes, mysql still shows processmodelos_de_prueba.py
class TestUser(object): def test_add_new(self, db_session): u = User.create(name='test_name') assert u.name == 'test_name' # if I put db.session.commit() here, tables won't drop