根据相关列值插入列

2024-04-19 07:51:18 发布

您现在位置:Python中文网/ 问答频道 /正文

这似乎是一个真正的初学者问题,但我很难找到一个简单的答案。我用一个表示一对多关系的简单数据模型将其简化为简单的部分:

class Room(db.Model):
    __tablename__ = 'rooms'
    id        = db.Column(db.Integer, primary_key=True)
    name      = db.Column(db.String(128), unique=True)
    capacity  = db.Column(db.Integer)
    events    = db.relationship('Event', backref='room')


class Event(db.Model):
    __tablename__ = 'counts'
    id               = db.Column(db.Integer, primary_key=True)
    unusedCapacity   = db.Column(db.Integer)
    attendance       = db.Column(db.Integer)
    room_id          = db.Column(db.Integer, db.ForeignKey('rooms.id'))

Event.unusedCapacity被计算为Room.capacity - Event.attendance,但是我需要在列中存储值-Room.capacity可能会随着时间的推移而改变,但是Event.unusedCapacity需要反映事件发生时实际未使用的容量。你知道吗

我当前正在查询房间,然后创建事件:

room = Room.query.get(room_id) # using Flask sqlAlchemy
event = event(unusedCapacity = room.capacity - attendance, ...etc) 

我的问题是:有没有更有效的方法一步到位?你知道吗


Tags: eventidtruedbmodelcolumnintegerclass
2条回答

SQLAlchemy向所有模型类添加了一个隐式构造函数,该类接受所有列和关系的关键字参数。您可以覆盖此选项并传递kwargs而不使用unusedCapacity,并在构造函数中获取房间容量:

class Event(db.Model):
    # ...
    #kwargs without unusedCapacity
    def __init__(**kwargs):
        room = Room.query.get(kwargs.get(room_id))
        super(Event, self).__init__(unusedCapacity = room.capacity - kwargs.get(attendance), **kwargs)


#Create new event normally
event = Event(id = 1, attendance = 1, room_id = 1)

正如@supershot的注释所指出的,insert上的查询可以计算数据库中未使用的容量,而不必首先获取。一个显式构造函数,如@toofeart所示,可以传递一个标量子查询作为unusedCapacity

class Event(db.Model):
    ...
    def __init__(self, **kwgs):
        if 'unusedCapacity' not in kwgs:
            kwgs['unusedCapacity'] = \
                db.select([Room.capacity - kwgs['attendance']]).\
                where(Room.id == kwgs['room_id']).\
                as_scalar()
        super().__init__(**kwgs)

虽然可以使用client-invoked SQL expressions作为默认值,但我不确定如何在不使用context-sensitive default function的情况下引用要插入表达式中的值,但这并没有完全解决:标量子查询没有内联,SQLAlchemy尝试使用占位符来传递它。你知道吗

__init__方法的一个缺点是,不能使用为模型创建的表执行批量插入来处理未使用的容量,但必须执行手动查询。你知道吗

另一件需要注意的事情是,在刷新发生之前,新unusedCapacity对象的Event属性保存的是SQL expression对象,而不是实际值。@toofeart的解决方案在这方面更加透明,因为新的Event对象将保存get go中未使用容量的数值。你知道吗

相关问题 更多 >