Question

I am starting with Flask sqlalchemy, but i don't understand how works the demo of the homepage (here).

This will create the structure:

>>> from yourapplication import db
>>> db.create_all()

But I don't understand where these users are stored.

>>> from yourapplication import User
>>> admin = User('admin', 'admin@example.com')
>>> guest = User('guest', 'guest@example.com')
>>> db.session.add(admin)
>>> db.session.add(guest)
>>> db.session.commit()

Because if I do Select * from user;

I will get:

test=# \dt
        List of relations
 Schema | Name | Type  |  Owner
--------+------+-------+----------
 public | user | table | postgres
(1 row)

test=# select * from user;
 current_user
--------------
 postgres
(1 row)

However the output is the expected:

>>> users = User.query.all()
>>> [<User u'admin'>, <User u'guest'>]

So, what is happening here? the users are stored in cache? memory? Because i don't see any admin or guest in the user table .

Was it helpful?

Solution

Flask is using the extremely unfortunate table name user. This is a reserved keyword in the database; an alias for the built-in user function, which is in turn an alias for current_user. That's why you get the column-name current_user when you select * from user; you're really running the pseudo-function current_user.

This is made more confusing by the fact that "user" doesn't use SQL function syntax, it's undecorated, and by the fact that it's rewritten by the parser so there's no function by that name actually defined, hence the confusing outcome:

regress=> explain select * from user;
                             QUERY PLAN                             
--------------------------------------------------------------------
 Function Scan on "current_user"  (cost=0.00..0.01 rows=1 width=64)
(1 row)

If you want to describe or select from the user-defined table named user you must, per the documentation on reserved words, quote it. So you must write:

select * from "user";

or

select * from public."user";

(schema-qualified).

Similarly:

\dt "user"

will show the table structure.

Please report a bug against Flask. It should not be using an SQL-92 reserved word as a relation name.

EDIT: Flask is creating a table called 'user' because the classname is User. In order to avoid this, it is recommended to provide a __tablename__ option while defining the model.

class User(db.Model):
    __tablename__= 'MyUser'
....

This way, you can avoid the conflicts with default conventions of the database.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top