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

Python flask_sqlalchemy:AbstractConcreteBase在查询子类之前不映射,python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,我目前正在从事一个涉及flask和sqlalchemy框架的项目。基本理念是建立一个票务系统,提供不同种类的票务 我的代码的简化版本可以在这里找到:(runnable throughpython app.py) 设置涉及一组模型,它们是: Base:所有模型的基类,基本上只定义一个id和表名 TimestampMixin:用于向模型添加时间戳的mixin,如创建或更新时间戳 门票:我目前遇到麻烦的主要原因。用于各种票据的抽象基类 TestTicket:一些用于演示的ticket类 我目前

我目前正在从事一个涉及flask和sqlalchemy框架的项目。基本理念是建立一个票务系统,提供不同种类的票务

我的代码的简化版本可以在这里找到:(runnable through
python app.py

设置涉及一组模型,它们是:

  • Base:所有模型的基类,基本上只定义一个
    id
    和表名

    • TimestampMixin:用于向模型添加时间戳的mixin,如创建或更新时间戳

    • 门票:我目前遇到麻烦的主要原因。用于各种票据的抽象基类

    • TestTicket:一些用于演示的ticket类

我目前的问题如下:

当尝试查询
票证
类时,我将收到如下错误:

sqlalchemy.exc.InvalidRequestError:应为SQL表达式、列或映射实体-获取“”

完整堆栈跟踪:

我用我的设置做了很多实验,但没有成功。随机地,我尝试在初始查询之前向子类添加一个查询,结果成功了

在深入研究代码之后,当查询子类时,似乎首先配置了映射器。查询基类时不会发生这种情况

这在我上面链接的示例中得到了演示(
app.py
,第15行ff)。如果我访问端点,第一个查询将失败。执行第二个查询(有效)后,最初失败的查询现在可以工作:

查询失败
第二次尝试查询成功
127.0.0.1---[25/Oct/2016 14:42:22]“GET/HTTP/1.1”200-

现在。。。在SQLAlchemy中配置映射器是否存在明显的问题


提前谢谢

如果从
AbstractConcreteBase
继承,它将推迟为该基类创建
Mapper
对象

在调用
configure\u mappers
之前,不会配置映射间关系。调用
configure\u mappers
的点包括将映射类实例化为实例时,以及使用
Session.query()
方法时

此外,由于您从
AbstractConcreteBase
继承,因此不会对持久性表进行映射,而且
Ticket
类永远不会直接实例化。因此,当您第一次调用
Ticket
上的查询时,没有
Ticket
表,也没有任何内部映射关系,从而导致您提到的错误

当您查询
TestTicket
时,调用
configure\u mappers
并创建映射器间关系,允许您查询
Ticket

如果创建一个实例
TestTicket
而不是查询它,您应该会看到相同的行为,因为此事件还将导致调用
configure\u mappers

如果您希望为
Ticket
类创建一个持久表,那么应该从
ConcreteBase
继承


正如您的发现所证明的,手动调用
configure\u mappers
似乎可以解决此问题。

感谢您的回复。您是对的,创建
TestTicket
也很有效<代码>票证不是持久化的,而是可查询的基类。根据中给出的示例,我应该能够直接查询基类。我知道映射器配置在这里被延迟了,但是为什么它根本没有发生呢?我可以手动触发吗?@Birne94我原以为它会在所有模型都定义好之后进行配置。我相信可能没有定义鉴别器(
mapper_args
中的
polymorphic_on
字段),如果您想进行多态加载(通常的情况;我相信这就是您想要的)——如果没有定义,可以在查询类时使用的派生select语句中定义它,但这不是典型的配置。和/或尝试使用_polymopic查询票证——我不能100%确定这一点,或者您是否可以手动调用
配置映射器
。值得一试。无论是在上添加
polymorphic\u,还是在
上使用
和_polymorphic
都不会产生有效的查询。我通过在应用程序启动时调用
configure\u mappers
解决了这个问题,它似乎正确地配置了所有内容。@Birne94很高兴听到您能够找到这个解决方案!在我看来有点独特,它不会被自动调用,就像“在大多数情况下”应该发生的那样。以前从未遇到过这种情况。无论如何,干杯!