Dra*_*agu 5 python sqlalchemy flask flask-sqlalchemy
我遇到了 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)
Run Code Online (Sandbox Code Playgroud)
u1 = # user 1
u2 = # user 2
...
f = Follower()
f.user_followed = u2
u1.following.append(f)
db.session.commit()
Run Code Online (Sandbox Code Playgroud)
f = Follower()
f.user_followed = u2
u1.following.remove(f)
db.session.commit()
Run Code Online (Sandbox Code Playgroud)
ValueError: list.remove(x): x not in list
Run Code Online (Sandbox Code Playgroud)
我明白为什么它不起作用,这是因为这个 Follower() 实例不在列表 u1.following 中。那么,我怎样才能删除这个关系呢?
您可以覆盖__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())
Run Code Online (Sandbox Code Playgroud)