为啥 SQLalchemy create_all() 可以重用?

Posted

技术标签:

【中文标题】为啥 SQLalchemy create_all() 可以重用?【英文标题】:Why SQLalchemy create_all() can be reused?为什么 SQLalchemy create_all() 可以重用? 【发布时间】:2016-04-20 19:41:46 【问题描述】:

我对数据库和 SQLalchemy/sqlite3 的背景知识知之甚少,但我对这些的实验告诉我 create_all() 几乎可以像“初始化数据库(如果它已经存在)”一样使用。

这是我写的flask webapp的“表单提交”部分:

db = SQLAlchemy(app)
@app.route('/submit', methods=['POST'])
def submit():
    form = UserForm(request.form)
    if request.method == 'POST':
        new_entry = User(form.username.data,
                         form.password.data)
        db.create_all()
        add_entry(new_entry)

db.create_all() 应该创建一个本地 .db 文件。如果我已经拥有该文件,并且我向表单提交了新数据,那么发生的情况是 new_entry 被附加到数据库表中,而不是覆盖 .db 文件。任何人都可以确认这个结果是预期的吗?如果执行不善,那么处理数据库初始化的更好方法是什么?

【问题讨论】:

我想不出任何你想在每个网络请求上运行db.create_all() 的情况,而是像@ThiefMaster 建议的那样做,或者在 Flask 应用启动任务中做一次。跨度> 【参考方案1】:

create_all 确实只创建了do not exist 的表。它不是用于迁移,而是用于在空数据库中创建初始结构。

您需要 alembic 进行迁移,可能通过 Flask-Migrate


除此之外,在 Flask 应用程序的面向 Web 的部分中包含任何与数据库结构相关的代码都是值得怀疑的。通常你在命令行工具(通过 Flask-Script 或单击)中执行此类操作,例如python manage.py create_db.

我不同意您关于“执行不力”的观点。它的实施方式可以阻止您做错误(并且可能是危险的)事情。假设您重命名一列。 “智能”create_all 将删除旧列(毕竟它已经消失了)并创建一个新列 - 任何工具都不可能知道您重命名了它而不是删除和添加一个。

【讨论】:

您能否详细说明“在您的 Flask 应用程序的面向 Web 的部分中有任何与数据库结构相关的代码是有问题的”? 通常您不想从 Web 界面执行数据库结构修改。这是您在部署(新)版本后通常会执行的操作(您也不会通过网络执行此操作) 通过“如果执行不力,处理数据库初始化的更好方法是什么?”,OP 并不是说​​create_all() 执行不善。他想知道在 他的 实现不是最好的情况下进行数据库初始化的更好方法是什么。换句话说,他想说:“我想知道如果我做错了应该怎么做”。 @Chupo_cro 你迟到了 5 年 ;) FWIW,我在他发布问题后的 2 分钟内回答了问题,所以他可能在编辑中更清楚地编辑了它 - without-a-new-修订宽限期(我认为是/曾经是 5 分钟)。 我知道这是 5 年前的事了,但答案可能总是会得到改进,并且此页面的主要目的是为将来存档信息。目前,这些句子:“我不同意您对“执行不力”的看法。它的执行方式是阻止您做错误(并且可能是危险的)事情。”,令人困惑,因为它们不在上下文中这个问题。 '我不同意你对“执行不力”的看法'这句话暗示了 OP 说 create_all() 没有很好地执行,但这不是他想说的。

以上是关于为啥 SQLalchemy create_all() 可以重用?的主要内容,如果未能解决你的问题,请参考以下文章

与 db.create_all() SQLAlchemy Python3.6 相关的问题

让 SQLAlchemy 在 create_all 上发布 CREATE SCHEMA

如何使用 create_all() 跨文件的 sqlalchemy orm 对象

FLASK SQLALCHEMY create_all() 不工作

SQLAlchemy 没有提供密码错误

sqlalchemy 创建表