【问题标题】:models are not detectable by flask migrate烧瓶迁移无法检测到模型
【发布时间】:2019-02-11 14:25:57
【问题描述】:

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

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

这是模型目录中的 __init_.py

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

# 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 时,未检测到模型文件夹中的类:

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 内的单个文件中。

请帮忙

谢谢

编辑 我也试过这个:

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 变量。 即使我在模型类中这样做:

from util import db 

它不会改变任何东西

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

【问题讨论】:

    标签: python flask-sqlalchemy flask-migrate


    【解决方案1】:

    我认为你是在正确的轨道上。首先,您需要在整个应用程序中使用相同的db。我会将一个保留在 util.py 中并删除所有其他的。

    之后,您需要确保在运行 util.py 时导入模型。我看到您正在尝试巧妙的方法将所有模型导入您的 model 包中。我喜欢对所有模型进行显式导入,而不是这种类型的自动导入,所以我的建议是你只需要一个一个地导入模型。

    为确保您的模型被识别,您应该做的最后一件事是删除或移走您的 SQLite 数据库。当您在删除数据库文件后运行db migrate 命令时,您应该会得到一个包含所有内容的迁移。

    【讨论】:

      【解决方案2】:

      您没有导入模型

      db = SQLAlchemy(app)
      # import the models
      migrate = Migrate(app, db)
      

      如果这无助于审查此问题。

      https://github.com/miguelgrinberg/Flask-Migrate/issues/50

      【讨论】:

      • 请检查更新。我导入模型,但什么也没发生
      猜你喜欢
      • 1970-01-01
      • 2018-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多