gpt4 book ai didi

python - 使用 sqlalchemy 关联代理正确级联删除

转载 作者:行者123 更新时间:2023-12-01 03:19:09 25 4
gpt4 key购买 nike

我在 sqlalchemy 中有一个自引用关系,该关系很大程度上基于发现的示例 in this answer .

我有一个用户表和一个将主要用户链接到次要用户的关联表。用户 A 可以是用户 B 的主要用户,B 可能也可能不是用户 A 的主要用户。它的工作原理与我上面链接的答案中的 Twitter 类比完全相同。

这工作得很好,只是我不知道如何为关联代理建立级联规则。目前,如果我删除一个用户,关联记录仍然存在,但它会清除已删除用户的所有 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 对象。这允许您设置级联行为。请参阅sqlalchemy documentation on backref arguments .

这里唯一需要的更改是在 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 对象而不是字符串。我还能够使外键列不可为空,因为它现在级联已删除的用户,以便关联也被删除。

关于python - 使用 sqlalchemy 关联代理正确级联删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42123785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com