Reputation: 61
My Flask site has Suggestions and Users.
class Suggestion(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_nickname = db.Column(db.Integer, db.ForeignKey('user.nickname'))
voters = db.relationship('User', secondary=votes, lazy='dynamic')
class User(db.Model):
id = db.Column(db.Integer, primary_key = True)
suggestions = db.relationship('Suggestion', backref='user', lazy='dynamic')
votes = db.relationship('Suggestion', secondary=votes, lazy='dynamic')
I have set up a many to many relationship between the two as such.
votes = db.Table('votes',
db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
db.Column('suggestion_id', db.Integer, db.ForeignKey('suggestion.id'))
)
When I try to delete a Suggestion inside my views.py I get an error.
The View:
@app.route('/_delete_suggestion', methods=['GET', 'POST'])
def delete_suggestion():
user_nickname = request.form.get('user_nickname')
user = User.query.filter_by(nickname=user_nickname).first()
sugg_id = request.form.get('sugg_id')
sugg = Suggestion.query.filter_by(id=sugg_id).first()
if user.is_special:
db.session.delete(sugg)
db.session.commit()
else:
flash('You are not cool enough to do that!')
return redirect(url_for('index'))
return
@app.route('/_upvote', methods=['GET', 'POST'])
def upvote():
user_nickname = request.form.get('user_nickname')
user = User.query.filter_by(nickname=user_nickname).first()
sugg_id = request.form.get('sugg_id')
sugg = Suggestion.query.filter_by(id=sugg_id).first()
if sugg.voters.filter_by(nickname=user_nickname).first() is not None:
print("ERR", file=sys.stderr)
else:
print("VOTED", file=sys.stderr)
sugg.score += 1
sugg.voters.append(user)
user.votes.append(sugg)
db.session.add(sugg)
db.session.add(user)
db.session.commit()
return
The Error:
StaleDataError: DELETE statement on table 'votes' expected to delete 2 row(s); Only 4 were matched.
What I Know:
What I Have Tried:
view-only=True
into the models.What am I missing? This is driving me up a wall!
EDIT: Inside a python interpreter, I tried to the following.
s = Suggestion.query.first()
for v in s.voters.all():
s.voters.remove(v)
s.voters.all()
This then crashed and produced the same StaleDataError.
Upvotes: 2
Views: 1417
Reputation: 61
I figured it out! I was adding into the Many to Many array twice inside the _upvote
route.
Original _upvote
snippet:
print("VOTED", file=sys.stderr)
sugg.score += 1
sugg.voters.append(user)
user.votes.append(sugg)
db.session.add(sugg)
db.session.add(user)
db.session.commit()
Fixed _upvote
snippet:
print("VOTED", file=sys.stderr)
sugg.score += 1
sugg.voters.append(user)
db.session.add(sugg)
db.session.commit()
Upvotes: 2