我第一次与SQLAlchemy和Flask一起创建API,并且尝试使用Entity Framework在.NET中做很多次我以前做过的事情,这是为我的CRUD操作创建一个模型,合并视图和表格中的列。我想知道是否有可能做,或者我想做的不是在Flask / SQLAlchemy中做到这一点的“正确”方法。我也在使用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)
Pigeon映射到表,PigeonView映射到视图(数据库是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和该鸽子被踢了多少次的整数。
(还有另一个名为“踢事件”的模型/表,该信息/来自此看起来像这样)
class KickEvent(db.Model):
__tablename__ = "kick_event"
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
pigeon_id = db.Column(db.Integer, db.ForeignKey('pigeon.id'), primary_key=True)
date = db.Column(db.DateTime)
我最终想要的是一个鸽子模型,其中包含Pigeon表中的所有内容以及Pigeon视图中的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中,我将执行以下操作将这些属性映射到我的最终目标Pigeon类:
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到达那里,因为整个过程显然与Entity Framework完全不同。
最佳答案
经过进一步的挖掘,我决定完全删除视图,将Pigeons附加到具有关系的KickEvents上,并添加column属性以求和。
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,这不是我的原始代码中的列)
我想这并不能真正回答我提出的问题,因为我没有将表格和视图组合在一起,但是完全摆脱了视图,我仍然得到了最终结果,那就是包含Pigeon表的单个模型和基于与Pigeon(KickEvent)有关系的表计算的值。
从这里获取所有这些信息:https://docs.sqlalchemy.org/en/13/orm/mapped_sql_expr.html
希望这对任何研究同一问题的人有所帮助。另外,如果我完全以错误的方式进行操作,请告诉我。我很想知道是否有更好的方法。