我试图使用Flask-SQLAlchemy限制一对多中'many'的数量。我希望每个'盲'行只允许3个或更少的'鼠标'(小鼠)。
这是我的基本设置......
class Blind(db.Model):
__tablename__ = 'blind'
#this __table_args__ does not work
#__table_args__ = ((db.CheckConstraint('length(blind_mice <= 3)')),)
id = db.Column(db.Integer, primary_key=True)
# I want to limit the blind_mice
#relationship to a count of 3 mice per 'Blind' id
blind_mice = db.relationship('Mouse')
class Mouse(db.Model):
__tablename__ = 'mouse'
id = db.Column(db.Integer, primary_key=True)
blind_id = db.Column(db.Integer, db.ForeignKey('blind.id'))
blind = db.relationship("Blind")
我尝试使用sqlalchemy的CheckConstraint(参见上面注释掉的__table_args__),但这会导致错误:
sqlalchemy.exc.OperationalError: (OperationalError) no such column: blind_mice u'\nCREATE
TABLE blind (\n\tid INTEGER NOT NULL, \n\tPRIMARY KEY (id), \n\tCHECK (length(blind_mice
<= 3))\n)\n\n' ()
感谢任何帮助。
答案 0 :(得分:0)
在解决这个问题几个小时后,我开始查看sqlalchemy事件文档。这是我能想到的最好的。
from sqlalchemy import event
from sqlalchemy.exc import IntegrityError
MAX_MICE_PER_BLIND = 3
class Blind(db.Model):
__tablename__ = 'blind'
id = db.Column(db.Integer, primary_key=True)
blind_mice = db.relationship('Mouse')
class Mouse(db.Model):
__tablename__ = 'mouse'
id = db.Column(db.Integer, primary_key=True)
blind_id = db.Column(db.Integer, db.ForeignKey('blind.id'))
blind = db.relationship("Blind")
@event.listens_for(Mouse.blind_id, 'set', retval=True)
def mice_per_blind_check(target, value, oldvalue, initiator):
if value is not None:
mice_count = Mouse.query.filter_by(blind_id=value).count()
if mice_count >= MAX_MICE_PER_BLIND:
orig = Exception('Maximum number of Mice ({}) '\
'reached for Blind.id = {}'\
.format(MAX_MICE_PER_BLIND, value))
msg = "Record Not Committed"
raise IntegrityError(msg, ';)', orig)
return value
此解决方案抛出IntegrityError,当与Flask-Restless一起使用时会导致HTTP 400错误请求,但不会中断Flask服务器操作。此外,该解决方案不允许存在具有blind_id = n的第4只鼠标。伟大的成功!