Currently working on CS50W's Project1, working with the GoodReads API. I thought the Register/Login/Logout requirements would be easy and quick for me to complete since I did it already with the CS50 Finance project. However, I am running into this issue:

TypeError: cannot pickle '_thread._local' object

This is what my Register code looks like:

@app.route("/register", methods=["GET", "POST"])
def register():
    """Register user"""
    if request.method == "POST":
        username1 = request.form.get("username")
        if not username1: # if they leave the space blank, return an apology
            return apology("Must provide a username", 403)

        # check to ensure the username is unique and doesn't already exist in the table
        checkuser = db.execute("SELECT * FROM users WHERE username = :username", {"username": username1}).fetchone()

        # etc etc etc

        # insert the new user into the table
        new_user_id = db.execute("INSERT INTO users (username, hash) VALUES (:username, :hash)", {"username": username1, "hash": hashedpass})

        # etc etc

My database is updating with new users that I register, but the website shows this error and I can't continue. Any pointers to why this may be happening?

  • And what is giving the error? Have you looked at the traceback? Commented Apr 7, 2020 at 14:26
  • Would it help to show some of the traceback? It's not clear to me whats triggering the error. return self.wsgi_app(environ, start_response), response = self.handle_exception(e), reraise(exc_type, exc_value, tb), raise value, response = self.full_dispatch_request(), return self.finalize_request(rv), response = self.process_response(response), self.session_interface.save_session(self, ctx.session, response), self.cache.set(self.key_prefix + session.sid, data,, and pickle.dump(value, f, pickle.HIGHEST_PROTOCOL). What I don't understand is none of the code I wrote is mentioned
    – azb1297
    Commented Apr 7, 2020 at 14:44

2 Answers 2


My assumption is you are not using CS50's SQL class. Therefore, this db.execute("INSERT INTO users (username, hash) VALUES (:username, :hash)", {"username": username1, "hash": hashedpass}) does not return the last inserted id. The CS50 SQL class does a lot of hard work for you. So new_user_id is an object (eg in sqlite a cursor object). So something like this session['user'] = new_user_id is storing that object. When it tries to read back and serialize the session variables (here self.cache.set(self.key_prefix + session.sid, data and here pickle.dump(value, f, pickle.HIGHEST_PROTOCOL) respectively), it throws the error.

What to do? Well, first you are going to need to familiarize yourself with the Postgres interface; according to the requirements.txt it is using the psycopg2 driver. This doc is one place to start exploring the available classes and methods for that driver to accomplish the same tasks that CS50 SQL class made so easy. You'll probably need to incorporate the lastrowid method of the cursor class to get the data you want. Good luck!

  • Just to clarify: by "CS50's SQL class" you mean when we used to from cs50 import sql? We were instructed to use Postgres for this project, and several tutorials I have found on registering/logins require ORMs - however, the project instructions state "You should not use the SQLAlchemy ORM (if familiar with it) for this project". Should I just ignore that and go the ORM route anyway? It seems to be the best bet.
    – azb1297
    Commented Apr 7, 2020 at 16:51
  • Yes, that's the import i mean. I'm not talking ORM at all. It is the driver that allows python to speak to postgres. The execute method is quite different between pyscog2 and cs50 sql. Let the learning begin! :) Commented Apr 7, 2020 at 16:56
  • oh man, I didn't even know we were allowed to use from cs50 import sql. I'll take a look. Thanks for the advice!
    – azb1297
    Commented Apr 7, 2020 at 17:02

As per @DinoCoderSaurus' answer/comments: I ended up importing sql from cs50 (you may need to pip install cs50 prior to including the import in your application.py file). So far, this seemed to fix my problems. I continued to use the ... :value", {"value": value}) style as above.

Note: I did check out the information about psycopg2, read very carefully and tried to implement that specific style, but ran into more problems than I had before. I like to think I didn't give up... but chose to save my sanity by proceeding with a tried-and-true method!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .