我第一次使用SQLAlchemy和Flask创建一个应用程序接口,我正在尝试做一些我以前使用实体框架在.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)
mySQL映射到一个表,PigeonView映射到一个视图( DB是Pigeon )。
这是视图:
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的模型/表,该信息来自于该模型/表,如下所示)
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)
作为最终结果,我想要的是一个鸽子模型,它包含了鸽子表中的所有内容以及鸽子视图中的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实现,因为整个过程显然与实体框架非常不同。
发布于 2020-02-02 13:25:42
在进一步研究之后,我决定完全取消视图,使用关系将鸽子附加到KickEvents,并添加一个列属性来计算总和。
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)关系的表计算的值的单一模型。
我从这里学到了所有这些:https://docs.sqlalchemy.org/en/13/orm/mapped_sql_expr.html
我希望这对任何研究同样问题的人都有所帮助。另外,如果我完全走错了路,请告诉我。我很想知道有没有更好的方法。
https://stackoverflow.com/questions/60022360
复制相似问题