[英]Properly cascade delete with sqlalchemy association proxy
我在sqlalchemy中具有自引用关系,该关系很大程度上基于此答案中的示例。
我有一个用户表,以及一个将主要用户链接到次要用户的关联表。 用户A可以是用户B的主要用户,而B可以是用户A的主要用户,也可以不是。
除我不知道如何为关联代理建立级联规则外,这工作正常。 当前,如果我删除用户,则关联记录仍然保留,但是它将对已删除用户的所有FK无效。 我希望删除级联到关联表并删除记录。
我还需要能够取消关联用户,这只会删除关联记录,但会传播到用户的“ is_primary_of”和“ is_secondary_of”关联代理。
谁能帮助我弄清楚如何将这些行为整合到我拥有的模型中? 代码如下。 谢谢!
import sqlalchemy
import sqlalchemy.orm
import sqlalchemy.ext.declarative
import sqlalchemy.ext.associationproxy
# This is the base class from which all sqlalchemy table objects must inherit
SAModelBase = sqlalchemy.ext.declarative.declarative_base()
class UserAssociation(SAModelBase):
__tablename__ = 'user_associations'
# Columns
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
# Foreign key columns
primary_user_id = sqlalchemy.Column(sqlalchemy.Integer,
sqlalchemy.ForeignKey('users.id', name='user_association_primary_user_fk'))
secondary_user_id = sqlalchemy.Column(sqlalchemy.Integer,
sqlalchemy.ForeignKey('users.id', name='user_association_secondary_user_fk'))
# Foreign key relationships
primary_user = sqlalchemy.orm.relationship('User',
foreign_keys=primary_user_id,
backref='secondary_users')
secondary_user = sqlalchemy.orm.relationship('User',
foreign_keys=secondary_user_id,
backref='primary_users')
def __init__(self, primary, secondary, **kwargs):
self.primary_user = primary
self.secondary_user = secondary
for kw,arg in kwargs.items():
setattr(self, kw, arg)
class User(SAModelBase):
__tablename__ = 'users'
# Columns
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
first_name = sqlalchemy.Column(sqlalchemy.String)
last_name = sqlalchemy.Column(sqlalchemy.String)
is_primary_of = sqlalchemy.ext.associationproxy.association_proxy('secondary_users', 'secondary_user')
is_secondary_of = sqlalchemy.ext.associationproxy.association_proxy('primary_users', 'primary_user')
def associate(self, user, **kwargs):
UserAssociation(primary=self, secondary=user, **kwargs)
事实证明非常简单。 原始代码中的backref只是字符串,但它们可以是backref对象。 这使您可以设置级联行为。 有关backref参数,请参见sqlalchemy文档 。
此处所需的唯一更改是在UserAssociation对象中。 现在显示为:
# Foreign key columns
primary_user_id = sqlalchemy.Column(sqlalchemy.Integer,
sqlalchemy.ForeignKey('users.id',
name='user_association_primary_user_fk'),
nullable=False)
secondary_user_id = sqlalchemy.Column(sqlalchemy.Integer,
sqlalchemy.ForeignKey('users.id',
name='user_association_associated_user_fk'),
nullable=False)
# Foreign key relationships
primary_user = sqlalchemy.orm.relationship('User',
foreign_keys=primary_user_id,
backref=sqlalchemy.orm.backref('secondary_users',
cascade='all, delete-orphan'))
secondary_user = sqlalchemy.orm.relationship('User',
foreign_keys=secondary_user_id,
backref=sqlalchemy.orm.backref('primary_users',
cascade='all, delete-orphan'))
现在,backref关键字参数是backref对象,而不是字符串。 我还能够使外键列不可为空,因为它现在级联已删除的用户,从而也删除了关联。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.