在SQLAlchemy中使用Session之间的“同步”苦苦挣扎

时间:2013-11-14 15:14:03

标签: python sqlalchemy pytest

我有一个创建的delete_entity函数删除了实体,我有一个测试这个函数的函数。

#__init__.py
engine = create_engine('sqlite://:memory')
Session = scoped_session(sessionmaker(engine))

# entity.py
def delete_entity(id, commit=False):
  """ Delete entity and return amount of amount of rows affected. """
  rows_affected = Session.query(Entity).filter(Entity.id == id).delete()
  if commit:
    Session.commit()
    # Marker @A

  return rows_affected

# test_entity.py
def test_delete_entity(Session):
   # ... Here I add 2 Entity objects. Database now contains 2 rows.

   assert delete_entity(1) == 1                 # Not committed, row stays in database.
   assert delete_entity(1, commmit=True)        # Row should be deleted 
   # marker @B 
   assert len(Session.query(Entity).all()) == 1

当我单独运行test_delete_entity() 时,此测试通过。但是,当我与其他测试一起运行此测试时,此测试失败。它在assert len(Session.query(Entity)).all()) == 1失败。查询找到2行,因此看起来该行尚未删除。 但是,当我在@A上使用Python调试器(pytest.set_trace())并查询数据库中的所有Entity对象时,我找到1行。因此删除查询已成功完成,并且已删除一行。但是当我在@B上查询所有实体行时,我得到2行。

我如何'同步'两个会话,所以我的测试将通过?

1 个答案:

答案 0 :(得分:0)

我刚试过但无法重现你的问题。这是我的完整脚本和结果:

import sqlalchemy as sa

from sqlalchemy import create_engine, Column, Integer, Unicode
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base


engine = create_engine('sqlite://', echo=True)

Base = declarative_base(bind=engine)
Session = scoped_session(sessionmaker(bind=engine))


class Entity(Base):
    __tablename__ = 'test_table'
    id = Column(Integer(), primary_key=True)
    name = Column(Unicode(200))


Base.metadata.create_all()

e1 = Entity()
e1.name = 'first row'
e2 = Entity()
e2.name = 'second row'

Session.add_all([e1, e2])
Session.commit()

print len(Session.query(Entity).all())
# CORRECTLY prints 2

rows_affected = Session.query(Entity).filter(Entity.id == 1).delete()
print rows_affected
# CORRECTLY prints 1
Session.commit()

print len(Session.query(Entity).all())
# CORRECTLY prints 1

由于您的脚本无法运行,我们无法找到您的问题。

请提供一个可运行的脚本,显示整个问题,就像我一样。脚本必须完成所有导入,插入数据,删除和查询。否则,我无法在我的环境中重现它。