相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Sqlalchemy.exc.InvalidRequestError: session in prepared state

I have built a social media like webapp which through infinite scrolling uploads more posts as you scroll. Though if I like a post as I am scrolling I get errors while in development mode.

I am using python/flask for backend.

If I scrolling my feed and simultaneously liking a post I get, in development mode, the errror

"sqlalchemy.exc.InvalidRequestError: This session is in 'prepared' state; no further SQL can be emitted within this transaction."

This has so far only happened in development mode and not in production mode but I am afraid that it will be a problem if more people start to use it.

Is this an error that will only be a problem in development or will this come up in production as well if I get a significant amount of users?

I have tried incorporating try except statements in my backend code which takes care of the error but it leads to other error so I would like to know if this is a problem that will be a larger issue later on or if it is only a problem in development?

Thanks

I tried adding a reproducible example but it was quite difficult

Beginning with the infinite scrolling. In this case I began by loading the indexes of the different posts

Front end

 <div   class="flow">
   <div class="flowpost" v-for="post in postlists" :key="post.id" >
     <PostTemplate :iterated_list ="post.id"  ></PostTemplate>

where postlists contains the id of the different posts

Script

  mounted(){
      window.onscroll = () => {
    let bottomOfWindow = document.documentElement.scrollTop + window.innerHeight === document.documentElement.offsetHeight;
    if (bottomOfWindow) {
      this.addmore()

The method addmore calls the get_index_list_of_posts function to load more posts

Backend

def get_index_of_list_of_posts():
    user_id = request.args.get("userid")
    group_action_id = request.args.get("group_action_id")
    page_nr = request.args.get("page_nr")
    total_pages = 0
    result_dict = {}
other_posts_query__ = Session.query(mvpUsersToPosts.id).filter(mvpPosts.id==mvpUsersToPosts.mvp_posts_id  ).order_by(mvpPosts.datetime.desc()) 
pagettt = Paginator(other_posts_query__, 4)
p = pagettt.page(page_nr)
post_query = p.object_list
result_post = []
postlist = []
for post  in post_query:
    result_post = {
        "message":message,
        "id": post[0]
    postlist.append(result_post)
result_dict_list = {}
result_dict_list["posts"] = postlist
result_dict_list["current_page_nr"] = page_nr
result_dict_list["total_page_nr"] = total_pages
posts_result = json.dumps(result_dict_list)
return posts_result

I then fill the posts with its data by calling the following backend function from the PostTemplate component.

def get_postlista_to_posttemplate():    
userid = request.args.get("userid")
postid = request.args.get("postid")
    result_post = []
    postlist = []
post_query = Session.query( mvpPosts,mvpUsers, mvpUsersToPosts,mvpSolutionTags).filter(mvpUsersToPosts.userid == mvpUsers.id ,mvpUsersToPosts.mvp_posts_id == mvpPosts.id, mvpUsersToPosts.id ==postid,   mvpPosts.id==mvpPostsToSolutionTags.mvp_posts_id, mvpSolutionTags.id==mvpPostsToSolutionTags.tagid).all()
    get_total_liked_query = Session.query( func.sum(mvpliked.liked)).filter(mvpliked.postid == postid).all()
    for post, users,user2post, tag  in post_query:
        result_post = {
            "postid": user2post.id,
            "mvp_post_postid" : post.id,
            "posttitle":post.posttitle,
            "posttype":post.posttype,
            "postimage":post.postimagevideo,
            'postliked':is_liked,
        postlist.append(result_post)
    posts_result = json.dumps(postlist)
return posts_result

The prepared state error occurs by the get_total_liked_query which I then wrapped in a try/except statement which did not help.

I can then like a post which is done with the following backend function.

  def like_post():
    reply = request.get_json()
    post_id = reply["post_id"]
    user_id= reply["user_id"]
    like_query = Session.query(mvpliked.liked).filter(mvpliked.postid == post_id, mvpliked.userid == user_id ).distinct(mvpliked.postid).all()
    if len(like_query) ==0:
        newrow = mvpliked(postid = post_id, userid = user_id, liked=1)
        Session.add(newrow)
        Session.commit()
    else:
        if (like_query[0][0] == 1):
            like_value = 0
        else:
            like_value = 1
        Session.query(mvpliked.liked).filter(mvpliked.postid == post_id, mvpliked.userid == user_id ).update({mvpliked.liked: like_value })
        Session.commit()
    return ""

The invalidrequest error seem to occur when functions like_post() and get_postlista_to_posttemplate() run simultaneously.

Session code

engine = create_engine(DATABASE_URL_prod)
Base = declarative_base(engine)
def  loadDatabaseSession():
    Base.metadata.create_all(engine)
    DatabaseSession = sessionmaker(bind=engine)
    DatabaseSession = DatabaseSession()
    return DatabaseSession
Session = loadDatabaseSession()
                Updated now, it is quite hard to create a small reproducible example since there are a lot of components involved but hopefully it clears the problem up a little. Thanks
– user12288003
                May 16, 2021 at 10:17
                Good question, I am not sure. I believe it is taken care of by the Sessionmaker.   From what I understand I only create a new session when I commit but I can be wrong   I have been using the following link: docs.sqlalchemy.org/en/14/orm/session_basics.html
– user12288003
                May 16, 2021 at 10:49
                If loadDatabaseSession is only called once then the problem may be that you are always using the same session (you can check by printing the session).  If that's the case this may be helpful.
– snakecharmerb - on strike
                May 16, 2021 at 12:58
                Yes it all seems to be the same session. I will check the link to try and fix it. Thanks for the help : )
– user12288003
                May 16, 2021 at 13:26
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.