Alembic自动生成空的Flask-SQLAlchemy迁移 [英] Alembic autogenerates empty Flask-SQLAlchemy migrations

查看:620
本文介绍了Alembic自动生成空的Flask-SQLAlchemy迁移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Alembic来处理Flask的迁移。在理论上, alembic修订版--autogenerate 应根据数据库中的更改自动生成迁移。但是,Alembic只是用上面的命令生成一个空白的迁移。



有一个问题非常类似于这个问题,问题是正确的模型没有被导入。但是,我已经从Flask应用程序中导入了模型,如 env.py 所示:

  ... 
#从Flask
导入设置alembic_config = config.get_section(config.config_ini_section)$ b $从开始导入应用程序$ b $从模型导入用户,项目,收件人#模型从models.py
导入此处alembic_config ['sqlalchemy.url'] = app.config ['SQLALCHEMY_DATABASE_URI']

engine = engine_from_config(
alembic_config, #config.get_section(config.config_ini_section)
prefix ='sqlalchemy。',
poolclass = pool.NullPool)
...
pre
$ b

除了导入的数据库元数据在 env.py ('start'是我的Flask应用程序的名称主文件):

  ... 
从开始导入db
target_metadata = db.metadata





正在运行 alembic revision --autogenerate -minitial_rev 然后generat这是一个空的迁移,虽然我的Flask应用程序会不同:

 initial_rev 

版本号:45296fd29540
修改:无
创建日期:2013-06-19 17:32:38.392268



#修订标识符,由Alembic使用。
revision ='45296fd29540'
down_revision = None

from alembic import op
import sqlalchemy as sa


def upgrade ():
###由Alembic自动生成的命令 - 请调整! ###
传递
###结束Alembic命令###


def downgrade():
###由Alembic自动生成的命令 - 请调整! ###
传递
###结束Alembic命令###



编辑



这是一个要点它显示我的应用程序的文件结构,以及一些额外的代码。看起来问题在于Alembic不喜欢从 database.py 导入的数据库没有在 __ init __。py中初始化初始化。但是,当使用蓝图时(因为周期性导入),这是不可能的,在这个答案中解释: https://stackoverflow.com/a/9695045/353878

所以问题是,如何使用Flamb蓝图也可以使用Alembic我甚至尝试过打印 db.metadata.sorted_tables

编辑#2



,以确保正确导入数据库元数据。果然,整个数据库模式都被传送到终端。那么为什么Alembic会产生空白的升级/降级功能?

编辑#3



我得出结论:问题与 db.init_app(app) db = SQLAlchemy(app)的区别有关。我不太确定是什么导致了这个问题。为了测试这个理论,我将 env.py 中的数据库import db 中的替换为 db = SQLAlchemy(app)。可能是一个坏主意,但我想看看会发生什么调试用途。

Alembic自动生成并填充了upgrade()和downgrade()方法 - ! upgrade()删除了所有三个表,而 downgrade()创建了所有三个表。我不知道这是为什么,但我希望这是有帮助的人试图找出这个问题。

解决方案

我怎么用Flamb和蓝图使用Alembic。



https://github.com/ davidism / basic_flask



我使用应用程序工厂模式,并在其中调用 db.init_app 。在 db = SQLAlchemy()之后导入所有将继承 db.Model 的模型,使得 db.metadata 知道它们;请注意,这不是在 create_app 工厂中完成的,而是在模块初始化期间内联。



运行 alembic ,项目文件夹不包含在 sys.path 中,所以我设置了它。然后,我从工厂创建一个应用程序,并从其配置中设置 sqlalchemy.url 。另外,我导入 db 并设置 target_metadata = db.metadata

无论项目结构如何,此设置对我来说都是一样的。我在一个包含蓝图的子包中包含了一组非常基本的用户模型和非常愚蠢的视图。只要确保在 load_models 中加载relavent模型,定义蓝图后导入视图,然后导入 init_views 。


I'm using Alembic to handle migrations for Flask. alembic revision --autogenerate should, in theory, autogenerate a migration based on changes in my database. However, Alembic is simply generating a blank migration with the above command.

There's a question very similar to this one, where the issue was that the proper models weren't being imported. However, I have imported the models from my Flask app, as shown in env.py:

...
# import settings from Flask
alembic_config = config.get_section(config.config_ini_section)
from start import app
from models import User, Item, Recipient # models are imported here from models.py
alembic_config['sqlalchemy.url'] = app.config['SQLALCHEMY_DATABASE_URI']

engine = engine_from_config(
            alembic_config, # config.get_section(config.config_ini_section)
            prefix='sqlalchemy.',
            poolclass=pool.NullPool)
...

As well as imported db metadata in env.py ('start' is the name of my Flask app's main file):

...
from start import db
target_metadata = db.metadata
...

Running alembic revision --autogenerate -m "initial_rev" then generates an empty migration, although my Flask app would beg to differ:

"""initial_rev

Revision ID: 45296fd29540
Revises: None
Create Date: 2013-06-19 17:32:38.392268

"""

# revision identifiers, used by Alembic.
revision = '45296fd29540'
down_revision = None

from alembic import op
import sqlalchemy as sa


def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    pass
    ### end Alembic commands ###


def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    pass
    ### end Alembic commands ###

Edit

Here is a gist that shows the file structure for my app, as well as some additional code. It seems the issue is that Alembic does not like having the db imported from database.py without being initialized first in __init__.py. However, this is not possible when blueprints are used (because of cyclical imports), explained in this SO answer: https://stackoverflow.com/a/9695045/353878.

So the question is, how can Alembic be used when Flask blueprints are used as well?

Edit #2

I even tried printing db.metadata.sorted_tables, to make sure the database metadata was being imported correctly. Sure enough, the whole database schema was piped to the terminal. So why is Alembic generating blank upgrade/downgrade functions?

Edit #3

I've concluded that the issue has something to do with the differences of db.init_app(app) and db = SQLAlchemy(app), but I'm not quite sure what is causing the issue. To test this theory, I replaced from database import db in env.py to be db = SQLAlchemy(app). Probably a bad idea, but I wanted to see what would happen for debugging purposes.

Alembic autogenerated and filled the upgrade() and downgrade() methods- except they were reversed! upgrade() dropped all three of my tables, while downgrade() created them with all the proper columns and metadata. I have no idea why this is, but I hope it is helpful to people trying to figure out this problem.

解决方案

Here is how I use Alembic with Flask and blueprints.

https://github.com/davidism/basic_flask

I use the application factory pattern and call db.init_app within that. After db = SQLAlchemy() I import all models that will subclass db.Model so that db.metadata is aware of them; note this is not done in the create_app factory, but just inline during module init.

When running alembic, the project folder is not included in sys.path so I set that up. Then I create an app from the factory and set sqlalchemy.url from its configuration. Also, I import db and set target_metadata = db.metadata.

This setup works for me all the time, no matter the project structure. I included a very basic set of user models and a very dumb view in a subpackage with a blueprint. Just make sure to load the relavent models in load_models, import the views after defining the blueprint, and import the blueprints in init_views.

这篇关于Alembic自动生成空的Flask-SQLAlchemy迁移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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