flask_sqlalchemy:在查询子类之前,不会映射AbstractConcreteBase

时间:2016-10-25 12:45:28

标签: python flask sqlalchemy flask-sqlalchemy

我目前正在开发一个涉及框架烧瓶和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中配置映射器是否存在实际问题?

提前致谢!

1 个答案:

答案 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似乎可以解决这个问题。