问题
I have a website on PythonAnywhere that uses Flask and Flask-SQLAlchemy connected to a MySQL database. Users can use the website to queue a task that is saved to the database as a record in a table, and then a separate scheduled task (Python program) checks the database and handles every unhandled record.
The problem I'm encountering is that the scheduled task's db query seems to only find new records when it runs for the first time, but if I then use the website to add a new task, the still-running scheduled task's recurring db queries (every 5 seconds) don't seem to detect the new record.
Any ideas about what could be happening here?
Here's the code being run by the bash file:
def generate_any_pending_videos():
unfinished_videos = db.session.query(Video)\
.filter(~Video.status.has(VideoStatus.status.in_(['Error', 'Finished', 'Video deleted'])))\
.order_by(Video.datetime_created)\
.all()
for video in unfinished_videos:
try:
logging.info("Attempting to create video for video %d" % video.id)
generate_video(video)
except Exception as e:
logging.error(str(e))
if __name__ == '__main__':
while True:
generate_any_pending_videos()
time.sleep(5)
回答1:
All SqlAlchemy queries run inside a transaction by default http://docs.sqlalchemy.org/en/latest/orm/session_transaction.html . That's the reason you are only getting new data in the first call of your script. Because inside a transaction seen data won't change, that is the I in ACID, transactions are isolated. After the commit or rollback the next query starts a new transactions, so you will get fresh data from the database.
回答2:
Found a fix: for some reason running db.session.commit()
before my query made the new records show up.
if __name__ == '__main__':
while True:
generate_any_pending_videos()
time.sleep(5)
db.session.commit() # For some reason this is needed to be able to detect newly-created videos
来源:https://stackoverflow.com/questions/52156515/flask-sqlalchemy-session-object-not-seeing-changes-to-the-database