为啥 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 对象