烧瓶迁移无法检测到模型 [英] models are not detectable by flask migrate

查看:131
本文介绍了烧瓶迁移无法检测到模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的烧瓶应用程序中有这棵树:

I have this tree in my flask application:

-- api
   -- migrations
   -- model
      -- __init__.py
      -- Persons.py
      -- Comments.py
      -- other_classes.py
   -- resources
   -- __init__.py
   -- app.py
   -- util.py

这是来自模型目录的 __init_.py :

This is __init_.py from model directory:

from os.path import dirname, basename, isfile
import glob
modules = glob.glob(dirname(__file__)+"/*.py")
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
from .Persons import Persons

这是util.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
import os
import model 

def create_app():
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] =  os.environ['DATABASE_ENGINE'] + '://' + \
                                         os.environ['DATABASE_USERNAME'] + ':' + \
                                         os.environ['DATABASE_PASSWORD'] + '@' + \
                                         os.environ['DATABASE_SERVER'] + '/api_rest?charset=utf8'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
    return app

app = create_app()
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)


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

这是app.py

from util import app
from flask import Flask, jsonify
from flask_restful import reqparse, abort, Api, Resource


@app.errorhandler(404)
def not_found(e):
    return jsonify({'message' : 'Not Found'}), 404

@app.errorhandler(500)
def internal_server_error(e):
    return jsonify({'message' : 'Internal Server Error'}), 500

api = Api(app)

class Overview(Resource):
    def get(self):
        return {'hello': 'world'}

api.add_resource(Overview, '/v1/api/overview')


if __name__ == '__main__':
    app.run( host = '0.0.0.0', port = 5000, debug = True, threaded = True )

Persons.py

Persons.py

# coding=utf-8
import sys
import os
from flask_sqlalchemy import SQLAlchemy
sys.path.append(os.path.dirname(os.getcwd()))
db = SQLAlchemy()


class Persons(db.Model):

    id = db.Column( db.Integer, primary_key = True )
    name = db.Column( db.String(255) )
    firstname = db.Column( db.String(255) )
    lastname = db.Column( db.String(255) )

当我执行 python3.6 util.py db migrate 时,未检测到模型文件夹中的类:

When I do python3.6 util.py db migrate, the classes inside model folder are not detected:

INFO  [sqlalchemy.engine.base.Engine] SHOW VARIABLES LIKE 'sql_mode'
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] SELECT DATABASE()
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] show collation where `Charset` = 'utf8' and `Collation` = 'utf8_bin'
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin AS anon_1
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [sqlalchemy.engine.base.Engine] DESCRIBE `alembic_version`
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] SELECT alembic_version.version_num
FROM alembic_version
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] DESCRIBE `alembic_version`
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [sqlalchemy.engine.base.Engine] SHOW FULL TABLES FROM `dsiapi_rest`
INFO  [sqlalchemy.engine.base.Engine] ()
INFO  [alembic.env] No changes in schema detected.

我看了其他问题,但找不到任何线索. API的结构是否正确?我有很多表,并将它们拆分为文件.当我将它们直接放在util.py中时,迁移就可以了.但我不想将所有内容都放在一个文件中.这就是为什么我需要将每个表放在/model文件夹内的单个文件中.

I have looked in the other questions but I can't find any clue. Is the structure of the API correct? I have so many tables and I split them in files. When I put them directly inside util.py the migration works. but I don't want to put everything in one single file. That's why I need to put each table in a single file inside the folder /model .

请帮助

谢谢

编辑 我也尝试过:

MODELS_DIRECTORY = "models"
EXCLUDE_FILES = ["__init__.py"]

def import_models():
    for dir_path, dir_names, file_names in os.walk(MODELS_DIRECTORY):
        for file_name in file_names:
            if file_name.endswith("py") and not file_name in EXCLUDE_FILES:
                file_path_wo_ext, _ = os.path.splitext((os.path.join(dir_path, file_name)))
                module_name = file_path_wo_ext.replace(os.sep, ".")
                importlib.import_module(module_name)

它没有检测到模型类.

我认为问题在于我在util中没有使用与模型中相同的db变量. 即使在模型类内部进行操作,也可以:

I think the problem is that I don't use the same db variable in util as in the models. Even when I do inside the model classes:

from util import db 

它什么都不会改变

我看到了周围的例子,但其中没有一个有那么多模型.当表太多时,将所有表放入一个文件中不是一个好习惯.拆分它们并将它们放在文件夹中是一个好主意,但似乎不起作用.

I have seen examples around but none of them has as much models in them. When we have too many tables it's not a good practice to put all of them in one file. Splitting them and making them inside a folder is a good idea but it doesn't seem working.

推荐答案

我认为您的做法正确.首先,您需要在整个应用程序中使用相同的db.我会将其中一个保留在util.py中,然后删除所有其他内容.

I think you are on the right track. First of all, you need to use the same db across your entire application. I would keep the one in util.py and remove all others.

在那之后,您需要确保在运行util.py时导入了模型.我看到您正在尝试聪明的方法,将所有模型导入到model包中.我赞成对所有模型进行显式导入,而不要对这种类型的自动导入进行导入,因此我的建议是只逐个导入模型.

After that, you need to make sure that when you run util.py the models are imported. I see that you are trying clever ways to get all your models imported into your model package. I favor doing explicit imports of all your models instead of this type of automatic imports, so my recommendation is that you just import the models one by one.

确保模型可以识别的最后一件事是删除或移走SQLite数据库.删除数据库文件后运行db migrate命令时,应该进行包含所有内容的迁移.

The final thing you should do to make sure your models are recognized is to delete or move away your SQLite database. When you run the db migrate command after you removed the database file, you should get a migration with everything in it.

这篇关于烧瓶迁移无法检测到模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆