我有一个基本的Person
表。每个人最多可以有5个朋友。我希望强制执行检查数据库级约束。
我已尝试使用此处所述的func.count
(http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#counting),但没有成功,收到此错误:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) misuse of aggregate function count()
这是我的代码:
friend_table = Table(
'friend', Base.metadata,
Column('left_id', Integer, ForeignKey('person.id')),
Column('right_id', Integer, ForeignKey('person.id'))
)
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
friends = relationship('Person',
secondary=friend_table,
primaryjoin=friend_table.c.left_id == id,
secondaryjoin=friend_table.c.right_id == id)
__table_args__ = (
CheckConstraint(func.count(friends) < 5, name='max_friends_constraint'),
)
答案 0 :(得分:0)
回答这个旧问题,因为我找不到其他令人满意的答案。根据我的调查,CheckConstraint
并不是使用JOIN查询是不可能的,但是效率很低。
但是,可以使用event
代替,检查append
出现时的号码,以强制最大数量的朋友。下面的代码示例应符合您的预期情况:
from sqlalchemy import event
from sqlalchemy.exc import IntegrityError
@event.listens_for(Person.friends, "append")
def receive_append(target, value, initiator):
if len(target.friends) >= 5:
# Raising this exc just as an example, just adapt to your needs
raise IntegrityError("person.friends.append", None, None)
# This returns the value, hence the friend will be appended normally
return value
如果仅打算使用sqlalchemy,这应该是一个很好的解决方案。如果您打算使用原始查询以任何其他形式与Db进行交互,则可能需要为关联表trigger
附加一个friend
来执行您的规则。