Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用sqlalchemy关联代理正确级联删除_Python_Sqlite_Sqlalchemy - Fatal编程技术网

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

Python 使用sqlalchemy关联代理正确级联删除,python,sqlite,sqlalchemy,Python,Sqlite,Sqlalchemy,我在sqlalchemy中有一个自我引用关系,它主要基于所发现的示例 我有一个用户表和一个将主用户链接到辅助用户的关联表。用户A可以是用户B的主要用户,B也可以是用户A的主要用户,也可以不是。它的工作原理与我上面链接的答案中的推特类比完全相同 这很好,只是我不知道如何为关联代理建立级联规则。当前,如果我删除了一个用户,关联记录将保持不变,但它会为删除的用户清除所有FK。我希望删除操作级联到关联表并删除记录 我还需要能够解除用户的关联,这只会删除关联记录,但会传播到用户的“is_primary_o

我在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对象。这允许您设置级联行为。看

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