我遇到了SqlAlchemy问题。
我只是想删除一个关系。这种关系由关联对象构成。
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
username = db.Column(db.String(255), unique=True)
password = db.Column(db.String(255))
following = db.relationship('Follower', foreign_keys='Follower.user_id')
followed_by = db.relationship('Follower', foreign_keys='Follower.follow_user_id')
def __repr__(self):
return '<%s (%i)>' % (self.username, self.id)
class Follower(db.Model):
__tablename__ = 'followers'
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
follow_user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
created_at = db.Column(db.DateTime, default=datetime.datetime.now)
user_followed = db.relationship("User", primaryjoin=(follow_user_id==User.id))
user = db.relationship("User", primaryjoin=(user_id==User.id))
def __repr__(self):
return '<%i %i>' % (self.user_id, self.follow_user_id)
u1 = # user 1
u2 = # user 2
...
f = Follower()
f.user_followed = u2
u1.following.append(f)
db.session.commit()
f = Follower()
f.user_followed = u2
u1.following.remove(f)
db.session.commit()
ValueError: list.remove(x): x not in list
我理解为什么它不起作用,因为这个Follower()实例不在列表u1.following中。那么,我该如何删除这种关系?
答案 0 :(得分:1)
您可以覆盖__eq__
,__ne__
和__hash__
,以便不是同一个实例但具有相同值的实例,比较和散列相等。
我为此目的使用以下mixin。只需覆盖子类中的compare_value
即可返回实际要比较的内容。
from sqlalchemy import inspect
class EqMixin(object):
def compare_value(self):
"""Return a value or tuple of values to use for comparisons.
Return instance's primary key by default, which requires that it is persistent in the database.
Override this in subclasses to get other behavior.
"""
return inspect(self).identity
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return self.compare_value() == other.compare_value()
def __ne__(self, other):
eq = self.__eq__(other)
if eq is NotImplemented:
return eq
return not eq
def __hash__(self):
return hash(self.__class__) ^ hash(self.compare_value())
答案 1 :(得分:0)
还可以先尝试查询对象,然后从列表中删除它。
follower_to_be_deleted = db.session.query(Follower).filter_by(user_id=u2.id).first()
u1.following.remove(follower_to_be_deleted)
db.session.commit()