烧瓶迁移无法检测到模型

时间:2019-02-11 14:25:58

标签: python flask-sqlalchemy flask-migrate

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

<DataTemplate x:Key="ImageItemTemplate">
    <Border Padding="10" Width="325" Height="350"
            BorderBrush="{DynamicResource SignificantInformationColorBrush}"
            BorderThickness="0" Margin="5" Background="Transparent" Focusable="True" MouseLeftButtonDown="ImageBorderOnMouseLeftButtonDown">
        <!--<Border.InputBindings>
            <MouseBinding MouseAction="LeftClick"
                          Command="{Binding Path=DataContext.SelectImageCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
                          CommandParameter="{Binding}" />
        </Border.InputBindings>-->
        <StackPanel>
            <Border BorderBrush="LightGray"
                    BorderThickness="1"
                    CornerRadius="1" Height="300" Width="300" Background="Transparent">
                <StackPanel Background="Black">
                    <Canvas Width="300" Height="300" VerticalAlignment="Center"
                            HorizontalAlignment="Center" Background="Transparent">
                        <Image Width="300" Stretch="UniformToFill" StretchDirection="DownOnly"
                               Source="{Binding BitmapImage}"
                               Height="300">
                            <Image.InputBindings>
                                <MouseBinding MouseAction="LeftDoubleClick"
                                              Command="{Binding Path=DataContext.OpenOriginalCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
                                              CommandParameter="{Binding}" />
                            </Image.InputBindings>
                        </Image>
                    </Canvas>
                </StackPanel>
            </Border>
            <StackPanel Orientation="Horizontal" Margin="1 10 0 0">
                <TextBlock Margin="5 0 0 0" TextAlignment="Center"
                           FontSize="11" Text="{Binding ImageInfo.SopInstanceUid}" Background="Transparent" />
            </StackPanel>
        </StackPanel>
    </Border>
</DataTemplate>

这是来自模型目录的 -- api -- migrations -- model -- __init__.py -- Persons.py -- Comments.py -- other_classes.py -- resources -- __init__.py -- app.py -- util.py

__init_.py

这是util.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

这是app.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()

Persons.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 )

当我执行 # 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

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

请帮助

谢谢

编辑 我也尝试过:

/model

它没有检测到模型类。

我认为问题在于我在util中没有使用与模型中相同的db变量。 甚至当我在模型类中进行操作时:

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)

它什么都不会改变

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

您不会导入模型

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

如果这不能帮助您查看此问题。

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