Python 烧瓶炼金术-最小应用

Python 烧瓶炼金术-最小应用,python,postgresql,sqlalchemy,flask,flask-sqlalchemy,Python,Postgresql,Sqlalchemy,Flask,Flask Sqlalchemy,我从炼金术开始,但我不明白主页的演示是如何工作的 这将创建以下结构: >>> from yourapplication import db >>> db.create_all() 但我不明白这些用户存储在哪里 >>> from yourapplication import User >>> admin = User('admin', 'admin@example.com') >>> guest = Use

我从炼金术开始,但我不明白主页的演示是如何工作的

这将创建以下结构:

>>> from yourapplication import db
>>> db.create_all()
但我不明白这些用户存储在哪里

>>> 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()
因为如果我从用户中选择*

我会得到:

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

test=# select * from user;
 current_user
--------------
 postgres
(1 row)
然而,输出是预期的:

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

那么,这里发生了什么?用户是否存储在缓存中?记忆力因为我在用户表中没有看到任何管理员或来宾。

Flask使用了非常不幸的表名user;内置用户函数的别名,它又是当前用户的别名。这就是为什么当您选择*from user时,会得到列名称current_user;您实际上是在运行伪函数current_user

由于用户不使用SQL函数语法,它是未修饰的,而且它是由解析器重写的,因此没有实际定义该名称的函数,因此这一点更加令人困惑:

regress=> explain select * from user;
                             QUERY PLAN                             
--------------------------------------------------------------------
 Function Scan on "current_user"  (cost=0.00..0.01 rows=1 width=64)
(1 row)
如果要从名为user的用户定义表中进行描述或选择,则必须根据有关保留字的文档将其引用。所以你必须写:

select * from "user";

模式限定

同样地:

\dt "user"
将显示表格结构

请报告烧瓶上的错误。它不应使用SQL-92保留字作为关系名称

编辑:Flask正在创建一个名为“user”的表,因为类名是user。为了避免这种情况,建议在定义模型时提供一个_tablename__;选项

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

这样,就可以避免与数据库的默认约定发生冲突

Flask使用了非常不幸的表名user;内置用户函数的别名,它又是当前用户的别名。这就是为什么当您选择*from user时,会得到列名称current_user;您实际上是在运行伪函数current_user

由于用户不使用SQL函数语法,它是未修饰的,而且它是由解析器重写的,因此没有实际定义该名称的函数,因此这一点更加令人困惑:

regress=> explain select * from user;
                             QUERY PLAN                             
--------------------------------------------------------------------
 Function Scan on "current_user"  (cost=0.00..0.01 rows=1 width=64)
(1 row)
如果要从名为user的用户定义表中进行描述或选择,则必须根据有关保留字的文档将其引用。所以你必须写:

select * from "user";

模式限定

同样地:

\dt "user"
将显示表格结构

请报告烧瓶上的错误。它不应使用SQL-92保留字作为关系名称

编辑:Flask正在创建一个名为“user”的表,因为类名是user。为了避免这种情况,建议在定义模型时提供一个_tablename__;选项

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

这样,就可以避免与数据库的默认约定发生冲突

你可能应该在某个地方配置你的数据库连接,我只是点击了链接,就好像在页面的中间。app.config['SQLALCHEMY\u DATABASE\u URI']='sqlite:////tmp/test.db“@njzk2”postgresql://postgres:xxx@localhost/test',如果我没有设置这个conf,显然程序会给出一个错误。不一定。默认的sqlite路径工作得很好。@njzk2可以,但问题不是这样。我有预期的输出,我只是想了解用户信息存储在哪里。您的postgresql表与预期的模式并不相似。因此,它存储在其他地方。你确定它不在SQLite文件中吗?你可能应该配置你的数据库连接,事实上,我只是点击了链接,就好像在页面的中间。app.config['SQLALCHEMY\u DATABASE\u URI']='sqlite:////tmp/test.db“@njzk2”postgresql://postgres:xxx@localhost/test',如果我没有设置这个conf,显然程序会给出一个错误。不一定。默认的sqlite路径工作得很好。@njzk2可以,但问题不是这样。我有预期的输出,我只是想了解用户信息存储在哪里。您的postgresql表与预期的模式并不相似。因此,它存储在其他地方。您确定它不在sqlite文件中吗?@user2990084您应该报告Flask的一个bug。自SQL-92以来,用户一直是SQL保留字。它不应该使用它。至少,Flask需要记录这将导致的怪癖。@CraigRinger:错误在于应用程序使用User作为类名,知道类名反过来被用作表名,并且在库中总是被引用,这不会带来任何问题。因此,在给出的烧瓶示例中。虽然大多数人在理想情况下看不到这个问题,但是应该使用_utablename_;=xyz覆盖默认表名,以避免这个问题。或者,使用不同的类名User@user2990084您应该报告烧瓶上的错误。自SQL-92以来,用户一直是SQL保留字。它不应该使用它。至少,Flask需要记录这将导致的怪癖。@CraigRinger:错误在应用程序中
将用户定义为类名,知道类名反过来被用作库中始终引用的表名,这不会带来任何问题。因此,在给出的烧瓶示例中。虽然大多数人在理想情况下看不到这个问题,但是应该使用_utablename_;=xyz覆盖默认表名,以避免这个问题。或者,使用该用户指定的其他类名