Python 如何使用SQLAlchemy将视图和表映射到一个模型?

Python 如何使用SQLAlchemy将视图和表映射到一个模型?,python,flask,sqlalchemy,flask-sqlalchemy,Python,Flask,Sqlalchemy,Flask Sqlalchemy,我第一次使用SQLAlchemy和Flask来创建API,并尝试使用Entity Framework在.NET中做了很多次的工作,即为我的CRUD操作创建一个模型,该操作将视图和表中的列组合在一起。我想知道这是否有可能,或者我在Flask/SQLAlchemy中尝试的方法是否“正确”。我也在使用炼金术库 以下是两个模型: class PigeonView(db.Model): __table_args__ = {'info': dict(is_view=True)} id = d

我第一次使用SQLAlchemy和Flask来创建API,并尝试使用Entity Framework在.NET中做了很多次的工作,即为我的CRUD操作创建一个模型,该操作将视图和表中的列组合在一起。我想知道这是否有可能,或者我在Flask/SQLAlchemy中尝试的方法是否“正确”。我也在使用炼金术库

以下是两个模型:

class PigeonView(db.Model):
    __table_args__ = {'info': dict(is_view=True)}
    id = db.Column(db.Integer, db.ForeignKey('pigeon.id')
    kick_events = db.Column(db.Integer)

class PigeonBase(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(255), nullable=False)
    date_created = db.Column(db.DateTime, nullable=False)
鸽子映射到一个表,鸽子视图映射到一个视图(数据库是mySQL)

这是一种观点:

CREATE VIEW pigeon_view AS 
    SELECT 
        p.id AS id, 
        COALESCE(SUM(k.pigeon_id), 0) AS kick_events 
    FROM pigeon p 
    LEFT JOIN kick_event k 
    ON p.Id = k.pigeon_id GROUP BY p.Id
基本上,只有一个鸽子ID和一个鸽子被踢了多少次的整数

(还有另一个名为Kick Events的模型/表格,该信息来自该模型/表格,如下所示)

我想要的最终结果是一个鸽子模型,它包含鸽子表中的所有内容以及鸽子视图中的kick_events列。(以及可能添加到鸽子视图的任何其他变量)

大概是这样的:

class Pigeon(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True) #from pigeon table
    name = db.Column(db.String(255), nullable=False) #from pigeon table
    date_created = db.Column(db.DateTime, nullable=False) #from pigeon table
    kick_events = db.Column(db.Integer) #from pigeon view
在.NET/Entity Framework中,我会这样做,将这些属性映射到我的最终目标鸽子类:

this.HasKey((x => x.Id));

this.Property(x => x.Name).HasColumnName("Name");
this.Property(x => x.DateCreated).HasColumnName("DateCreated");
this.Property(x => x.KickEvents).HasColumnName("KickEvents");

Map(m =>
{
    m.Properties(p => new
    {
        p.Id,
        p.Name,
        p.DateCreated
    });
    m.ToTable("Pigeon");
});

Map(m =>
{
    m.Properties(p => new
    {
        p.Id,
        p.KickEvents
    });
    m.ToTable("PigeonView");
});

但我不确定如何使用Python/SQLAlchemy实现这一点,因为整个过程显然与实体框架非常不同。

经过进一步挖掘,我决定完全放弃该视图,将鸽子附加到具有关系的KickEvents,并添加一个列属性来对kicks求和

class Pigeon(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(255), nullable=False)
    date_created = db.Column(db.DateTime, nullable=False)
    kick_events = db.Column(db.Integer)
    kick_events = relationship("KickEvent"),
    kick_count = column_property(
        select([func.count(KickEvent.id)]).\
            where(KickEvent.pigeon_id==id).\
            correlate_except(KickEvent))
(与解决方案无关,但我还修改了KickEvents,使其具有作为主键的Id,因为我决定希望用户能够多次踢同一只鸽子,因此我可以使用KickEvent.Id,它不是我原始代码中的一列)

我想这并没有真正回答我提出的问题,因为我并没有将表和视图结合起来,但在完全摆脱视图之后,我仍然得到了我想要的最终结果,即一个包含鸽子表的单一模型和一个基于与鸽子(KickEvent)相关的表计算的值

从这里得到了所有这些:


我希望这有助于任何人研究同样的问题。如果我完全错了,请告诉我。我很想知道是否有更好的方法。

在进一步挖掘之后,我决定完全放弃该视图,将鸽子附加到具有关系的KickEvents,并添加一个列属性来求kicks之和

class Pigeon(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(255), nullable=False)
    date_created = db.Column(db.DateTime, nullable=False)
    kick_events = db.Column(db.Integer)
    kick_events = relationship("KickEvent"),
    kick_count = column_property(
        select([func.count(KickEvent.id)]).\
            where(KickEvent.pigeon_id==id).\
            correlate_except(KickEvent))
(与解决方案无关,但我还修改了KickEvents,使其具有作为主键的Id,因为我决定希望用户能够多次踢同一只鸽子,因此我可以使用KickEvent.Id,它不是我原始代码中的一列)

我想这并没有真正回答我提出的问题,因为我并没有将表和视图结合起来,但在完全摆脱视图之后,我仍然得到了我想要的最终结果,即一个包含鸽子表的单一模型和一个基于与鸽子(KickEvent)相关的表计算的值

从这里得到了所有这些:

我希望这有助于任何人研究同样的问题。如果我完全错了,请告诉我。我很想知道是否有更好的方法