flask 有关 create_all 之前是否需要导入模型类的问题?

2018-07-11 11:15:39 +08:00
 sevenQu
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()

class Contact(db.Model):
    ...
from flask import Flask
from app.models import db

def create_app():
    app = Flask(__name__)

    # 绑定数据库
    db.init_app(app)


    # 下面两种方法都可以创建数据库
    db.create_all(app=app)

    # with app.app_context():
    #     db.create_all()

    return app

2975 次点击
所在节点    Flask
12 条回复
mink
2018-07-11 12:14:00 +08:00
不需要, 你在上面通过 from app.models import db 已经把模型和 db 绑定在一起了。create_app 中 db.init_app 是把 db 和当前的应用绑定在一起 只要使用 db.create_all 方法就可以调用 不需要引入模型
sevenQu
2018-07-11 12:47:44 +08:00
@mink 确实我试了,使用 db.create_all()确实可以创建数据库
sevenQu
2018-07-11 12:49:53 +08:00
@mink
```
import os
from app import create_app,db
from flask_script import Manager,Shell
from flask_migrate import Migrate,MigrateCommand

# from app.models.wordRepertory import CET4,CET6,Kaoyan


app=create_app(os.getenv('FLASK_CONFIG') or 'default')

manager=Manager(app=app)
migrate=Migrate(app=app,db=db)

def make_shell_context():
return dict(app=app,db=db)
manager.add_command('shell',Shell(make_context=make_shell_context))
manager.add_command('db',MigrateCommand)

if __name__=='__main__':
manager.run()
```


在使用 migrate 的时候,应该怎么做?我试了,如果不在上面引入 models 里定义的类,就无法迁移自动生成数据表,希望可以帮忙解决一下
mink
2018-07-11 15:14:24 +08:00
@sevenQu 我不清楚 migrate 会不会自动生成数据表, 但是可以通过 db.create_all()完成初始化
````python
@manager.command
def init():
db.create_all()

$ python manage.py init

```
mink
2018-07-11 15:18:36 +08:00
@sevenQu flask-migrate 的 init 只是创建 migrations 的相关文件后续需要执行,migration 和 upgrade 才会记录版本和生成迁移脚本执行数据库初始化 https://juejin.im/post/5b1935355188257d492ae266
sevenQu
2018-07-11 15:20:24 +08:00
@mink 会自己生成数据表的,可以完全不使用 create_all 创建。我自己试的结果是,前面需要引入 models 里的类,如果将 model 拆分,导入会很多,感觉不优雅也感觉没必要
sevenQu
2018-07-11 15:22:19 +08:00
@mink 谢谢,看来是不可避免的要引入了,十分感谢
lniwn
2018-07-11 15:47:29 +08:00
在 create_all 之前,要引入 models 文件,否则 Model 的 metadata 中没有你定义的类,你定义的表类最终会存储到 db.Model.metadata.tables 中,使用方式可以参考<https://github.com/lniwn/my_proxypool/blob/0a09c231d2f8ca7383899d8aa34153965948bd93/datacenter/datacenter.py#L38>。
这样不可避免的会导致循环引用的问题,一个比较好的解决方法是使用 import_string 来动态导入,这个方法在 werkzeug 中,我自己也参考着实现了一个<https://github.com/lniwn/my_proxypool/blob/0a09c231d2f8ca7383899d8aa34153965948bd93/datautil/generalutils.py#L8>
sevenQu
2018-07-11 17:14:42 +08:00
@lniwn 这段获取 db.Model.metadata.tables 里的表类的代码在 create_all()方法的源码里有,所以确实不需要引入 models 里的类
sevenQu
2018-07-12 11:27:50 +08:00
@lniwn 好像我错了,是需要导入 models 的,导入的话,还有几个问题,希望您可以帮忙看看,我把代码放到了 github,问题在 readme.md ,十分希望您可以帮忙解释一下,谢谢,https://github.com/seven-share/flaskMigrateTry
sevenQu
2018-07-12 11:30:07 +08:00
@mink 老铁,我又试了一下,发现不引入 models 是不能创建数据表的,希望您能看看我的源代码,看看是不是确实需要引入,同时我还有几个新问题写在了 github 的 readme 里,方便的话,希望您可以帮忙解决一下,十分感谢,https://github.com/seven-share/flaskMigrateTry
greyli
2018-07-17 19:53:47 +08:00
在知乎写了一个同一问题的回答,供需要的人参考:
https://www.zhihu.com/question/284904297/answer/444926077

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/469842

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX