Alembic / Flask-migrate不能识别数据库结构 [英] Alembic/Flask-migrate doesn't recognise database structure

查看:359
本文介绍了Alembic / Flask-migrate不能识别数据库结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于Flask的应用程序,我试图启用迁移来管理数据库结构变化。我的数据库不是空的,包含表和记录,然后才开始使用alembic和flask-migrate。



首先,我尝试使用alembic独立, pip install alembic ,然后配置所有内容并使用 autogenerate 生成diff。所有工作正常,但输出并不完全是我所期望的:

$ pre $ INF $ [alembic.autogenerate.compare]检测到删除的表u'用户
生成/Users/me/Documents/Project/app/migrations/versions/3de1151ce5de_.py ...完成

因此,表 user 实际存在于我的数据库中(我认为这是postgresql中的一个保留表),而且我从来没有删除它。另外,我还有一堆其他的表,看起来似乎是无形的。起初我以为我没有正确配置alembic,所以我开始了,决定尝试

任何想法我做错了什么?



编辑:我决定添加一些关于如何编辑原始的alembic env.py的重要信息:

  .... 
import sys,os sys.path.append(os.getcwd())
从app导入应用程序导入数据库
target_metadata = db.metadata

....

def run_migrations_online():
以在线模式运行迁移

在这种情况下我们需要创建一个引擎
并且把一个连接和上下文关联起来


#所有的模型需要导入,所以当迁移运行时它们是可见的
from app.models import Model1,Model2,Model3,Model4,Model5
$ b $ ...

这个变化对于alembic在任何迁移开始之前查看我的声明性基础和模型是必要的。放弃独立的方法后,我只是遵循烧瓶迁移教程,并没有触及任何文件。


$ b 编辑:好的,所以我们已经解释了删除的用户表。不过,我的其他模型并没有出现在脚本中。我认为会发生什么,因为应用程序是在创建迁移脚本之前启动的,所以sqlalechmy db.create_all()调用创建表,这就是为什么alembic没有看到colums vs vs楷模。也许我在错误的地方调用了 create_all()
$ b 编辑:是的!就是这样,我将 db.create_all()移到 manager.run()下面,它现在检测到了正确的更改。感谢您的帮助!

解决方案

您的数据库有一个 user 表,它不在任何SQLAlchemy模型中表示。然后,Alembic会假定你已经删除了这个表,因为所有的自动迁移脚本都会显示你的应用程序中定义的模型和实际的数据库。 Alembic没有办法知道你的数据库中有一个表格是免除迁移脚本的。



无论如何,自动迁移功能非常棒,但它不应该完全自动。您必须检查生成的脚本,并在使用它们之前修正所有错误或不准确之处。



向前移动的方法是编辑迁移脚本以更正此问题。把那张桌子拿走。迁移脚本是手动编辑,不要害怕这样做。

不幸的问题是,每次发出新的迁移时,表删除都会再次显示。我不认为Alembic有办法提供例外。


I have a Flask-based application and I'm trying to enable migrations to be able to manage database structural changes. My database is not empty and contains tables and records before I started with alembic and flask-migrate.

First, I tried to use alembic stand-alone, just pip install alembic and then configure everything and use autogenerate for generating the diff. All works fine but the output was not exactly what I expected:

INFO  [alembic.autogenerate.compare] Detected removed table u'user'
  Generating /Users/me/Documents/Project/app/migrations/versions/3de1151ce5de_.py ... done

So the table user actually is present in my database (I think it's a reserved table in postgresql) and I have never removed it. Also, I have a bunch of other tables which seem to be invisible to alembic. At first I thought I failed to configure alembic properly, so I started over and decided to try this nice flask extension by Miguel Grinberg. This was a lot easier to setup, but the result was exactly the same message.

Any ideas what am I doing wrong?

EDIT: I decided to add some important information on how I edited my original alembic env.py:

....
import sys,os sys.path.append(os.getcwd())
import app from app import db
target_metadata = db.metadata

....

def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    # all the models need to be imported so they are visible when migration runs
    from app.models import Model1, Model2, Model3, Model4, Model5

...

This changes were necessary for the alembic to see my declarative base and the models before any migration starts. After dropping the standalone approach I just followed the flask-migrate tutorial and didn't touch any files there.

EDIT: Ok, so we've got the deleted 'user' table explained. Still, my other models don't appear in the scripts. I think what happens is since the app is started before the migration scripts are created, the sqlalechmy db.create_all() call creates the tables and this is why alembic doesn't see any difference in the colums vs models. Perhaps I'm calling create_all() in the wrong place?

EDIT: Yes! That was it, I moved db.create_all() below the manager.run() and it detects the changes properly now. Thanks for all the help!

解决方案

Your database has a user table, which is not represented in any of your SQLAlchemy models. Correct?

Alembic will then assume that you have removed the table, since all the auto-migration script does is show the differences between the models defined in your application and the actual database. Alembic has no way to know that you have a table in your database that is to be considered exempt from migration scripts.

In any case, the automatic migration feature is great, but it is not supposed to be fully "automatic". You always have to review the generated scripts and fix any errors or inaccuracies before you use them.

The way to move forward is to edit the migration script to correct this. Just take that remove table away. Migration scripts are meant to be hand edited, don't be afraid to do that.

The unfortunate problem is that every time you issue a new migration that table remove will show up again. I don't think Alembic has a way to provide exceptions.

这篇关于Alembic / Flask-migrate不能识别数据库结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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