我目前正在开发一个涉及框架烧瓶和sqlalchemy的项目。基本的想法是拥有一个票务系统,提供不同类型的票证。
我可以在此处找到我的代码的简化版本:https://github.com/Birne94/flask-sqlalchemy-ticket-setup(可通过python app.py
运行)。
设置涉及一组模型,它们是:
基础:所有模型的基类,基本上只定义id
和表名
TimestampMixin:用于向模型添加时间戳的mixin,如创建或更新时间戳
票证:我目前遇到麻烦的主要原因。各种门票的抽象基类。
TestTicket:一些用于演示目的的门票类
目前的问题,我有以下几点:
尝试查询Ticket
课程时,我会收到如下错误:
sqlalchemy.exc.InvalidRequestError: SQL expression, column, or mapped entity expected - got '<class 'models.Ticket'>'
完整的堆栈跟踪:https://gist.github.com/Birne94/bac3254163c8248df192521729857641
我正在尝试我的设置,没有成功。随机地,我尝试在初始查询之前向子类添加一个查询,并且它有效。
深入研究代码之后,当查询子类时,首先会显示映射器。查询基类时不会发生这种情况。
这在我上面链接的示例(app.py
,第15行ff)中得到了证明。如果我访问端点,第一个查询将失败。执行第二个查询(有效)后,最初失败的查询现在将起作用:
query failed
query successful on second try
127.0.0.1 - - [25/Oct/2016 14:42:22] "GET / HTTP/1.1" 200 -
现在......是否有一些明显我遗漏/做错的事情,或者在SQLAlchemy中配置映射器是否存在实际问题?
提前致谢!
答案 0 :(得分:2)
如果从AbstractConcreteBase
继承,它将推迟为该基类创建Mapper
个对象。
在调用configure_mappers
之前,不会配置映射间关系。调用configure_mappers
的点包括将映射的类实例化到实例中以及何时使用Session.query()
方法。
此外,由于您从AbstractConcreteBase
继承,因此不会对持久表进行映射,并且永远不会直接实例化Ticket
类。因此,当您第一次在Ticket
上调用查询时,没有Ticket
表,也没有任何映射间关系,导致您提到的错误。
当您查询TestTicket
- configure_mappers
被调用并创建了映射器间关系时,您可以查询Ticket
。
如果您创建实例TestTicket
而不是查询它,您应该会看到相同的行为,因为此事件也会导致configure_mappers
被调用。
如果您打算为Ticket
类创建持久表,则应该继承ConcreteBase
。
正如您的调查结果所证明的那样,手动调用configure_mappers
似乎可以解决这个问题。