尝试删除行时引发sqlalchemy.orm.exc.StaleDataError

0 投票
1 回答
1612 浏览
提问于 2025-04-18 02:45

当我尝试删除用户和它的关联表 friends_notifications 之间的关系时,应用程序出现了一个错误,内容是 StaleDataError: DELETE statement on table 'friends_notifications' expected to delete 1 row(s); Only 0 were matched.

这是我的 数据库结构

friends_notifications = db.Table('friends_notifications',
    db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('friend_id', db.Integer, db.ForeignKey('user.id'))
)

class User(db.Model): 
    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String(50), unique = True)
    password = db.Column(db.String(50))
    email = db.Column(db.String(100), index = True, unique =True)
    age = db.Column(db.SmallInteger())
    about_user = db.Column(db.String(500))
    img_url = db.Column(db.String(120))  

    notify_friend = db.relationship('User',
        secondary = friends_notifications,
        primaryjoin = (friends_notifications.c.user_id == id),
        secondaryjoin = (friends_notifications.c.friend_id == id),
        lazy = 'dynamic'
    )

    def __init__(self, username, password, email, age, about_user, img_url):
        self.username = username
        self.password = password
        self.email = email
        self.age = age
        self.about_user = about_user
        self.img_url = img_url

还有一个 函数,用于在用户点击拒绝时删除通知

def deny_request(self, user, globalUser):
        if self.notify_friend.filter(friends_notifications.c.user_id == user.id).filter(friends_notifications.c.friend_id == globalUser.id).count() == 1:

            self.notify_friend.remove(user)
            return self

这个 视图 代码是这样的:

@app.route('/deny/<username>')

@login_required
def deny(username):
user = User.query.filter_by(username = username).first()

if user == None:
    flash ('Monkey ' + username + ' does not exists')
    return redirect(url_for('notifications'))
if user == g.user:
    flash ('You cannot deny your own friend request, since it doesn\'t exists')
    return redirect(url_for('notifications', username = username))
globalUser = g.user
u = user.deny_request(user, globalUser) 

if u is None:
    flash ('Request cannot be denied from ' + username + '!')
    return redirect(url_for('notifications', username = username))

db.session.add(u)
db.session.commit()

flash('Friend request to ' + username + ' was denied')
return redirect(url_for('notifications', username = username))

所以当我点击那个拒绝按钮时,它的引用是:

<a href="{{ url_for('deny', username = notif.username ) }}">deny</a>

然后就出现了 StaleDataError: DELETE statement on table 'friends_notifications' expected to delete 1 row(s); Only 0 were matched. 这个错误。我猜这意味着记录不存在,但实际上是存在的。我可能在删除记录时做错了什么,所以有没有其他正确的方法来做到这一点?? :(

1 个回答

1

这个问题是通过添加两个小功能和修改拒绝功能来解决的,具体如下:

    #used to deny friends request from other users
    def deny_request(self, user, globalUser):
        if self.notify_friend.filter(friends_notifications.c.user_id == user.id).filter(friends_notifications.c.friend_id == globalUser.id).count() == 1: #checking if the request exists
            return self.cancel_request(globalUser) #sending the request

    #current function is used to cancel requests that are sent by logged in user
    def cancel_request(self, user): 
        if self.request_exists(user):
            self.notify_friend.remove(user)
            return self

    def request_exists(self, user):
        return self.notify_friend.filter(friends_notifications.c.friend_id == user.id).count() > 0

撰写回答