postgresqlflask-sqlalchemypgadminrollback

Unwanted Rollback in Postgres - missing data after commit


I am trying to create a simple sign-up and login web app using Flask and PostgreSQL in Docker. I also added pgAdmin because I wanted to see my database. My web app has a strange problem. I am able to create new user (sign-up) and then also log in into the user I've created but if I check my database using pgAdmin it is empty. In logs I noticed that after every commit there's a rollback. I've been trying to debug it but with no success.

This is how I create new users :

new_user = User(email=email, username=username, password=password)
db.session.add(new_user)
db.session.commit()
login_user(new_user, remember=True)
flash('Account created!', category='success')
return redirect(url_for('home.html'))

This is how my User table looks :

class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
username = db.Column(db.String(150))

And this is a Rollback log:

"GET /sign-up HTTP/1.1" 200 -
Created Database! <----------- This is the second creation of database
INFO sqlalchemy.engine.Engine BEGIN (implicit)
INFO sqlalchemy.engine.Engine SELECT "user".id AS user_id, 
"user".email 
AS user_email, "user".password AS user_password, "user".username AS 
user_username 
FROM "user" 
WHERE "user".email = %(email_1)s 
LIMIT %(param_1)s
INFO sqlalchemy.engine.Engine [generated in 0.00048s] {'email_1': 
'test@test.test', 'param_1': 1}
INFO sqlalchemy.engine.Engine INSERT INTO "user" (email, password,             
username) VALUES (%(email)s, %(password)s, %(username)s) RETURNING                 
"user".id
INFO sqlalchemy.engine.Engine [generated in 0.00041s] {'email':     
'test@test.test', 'password': 'test', 'username': 'test'}
INFO sqlalchemy.engine.Engine COMMIT
INFO sqlalchemy.engine.Engine BEGIN (implicit)
INFO sqlalchemy.engine.Engine SELECT "user".id AS user_id, 
"user".email     
AS user_email, "user".password AS user_password, "user".username AS         
user_username 
FROM "user" 
WHERE "user".id = %(pk_1)s
INFO sqlalchemy.engine.Engine [generated in 0.00045s] {'pk_1': 1}
INFO sqlalchemy.engine.Engine ROLLBACK
"POST /sign-up HTTP/1.1" 302 -
INFO sqlalchemy.engine.Engine BEGIN (implicit)
INFO sqlalchemy.engine.Engine SELECT "user".id AS user_id, 
"user".email AS user_email, "user".password AS user_password, 
"user".username AS user_username 
FROM "user" 
WHERE "user".id = %(pk_1)s
INFO sqlalchemy.engine.Engine [generated in 0.00040s] {'pk_1': 1}
INFO sqlalchemy.engine.Engine ROLLBACK
"GET / HTTP/1.1" 200 -

I have also noticed in logs that the database is created twice. This is how I create a database

with app.app_context():   
    db.create_all()
    print('Created Database!')

The database gets created in the beggining, which is correct. Below are logs

CREATE TABLE "user" (
 id SERIAL NOT NULL, 
 email VARCHAR(150), 
 password VARCHAR(150), 
 username VARCHAR(150), 
 PRIMARY KEY (id), 
 UNIQUE (email)
)
Created Database!

And then when I access the sign-up page I get log 'Created Database!' again. Only the print statement.

"GET /sign-up HTTP/1.1" 200 -
Created Database!

Thank you for your answers and I am sorry if there is anything missing in my snippets. I will gladly provide more.


Solution

  • As you can see the database name is 'User'. Basic syntax for query is

    SELECT * 
    FROM table_name;
    

    But if you use my database name :

    SELECT * 
    FROM User;
    

    You'll get different table because 'user' is a reserved keyword in PostgreSQL.

    When a table name matches a reserved keyword, you need to enclose the table name in double quotes = "user".

    After enclosing, everything works as intended. Sorry for this beginner mistake.