我在开发过程中当创建完模型后执行了一次迁移和upgrade后(记做version1吧)更改了一个模板的字段也执行了migrate和upgrade(记做version2),但是最后发现想回退到version1即执行python 文件名.py db downgrade 版本号,后报错了错误如下(由于有太多的无用错误中间的删除了):
INFO [alembic.runtime.migration] Context impl MySQLImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running downgrade 67e517bde18c ->bc447eaaaab1, test2
Traceback (most recent call last):
File "test1.py", line 36, in
manager.run()
File"/home/jjw/.local/virtualenvs/flask/local/lib/python2.7/site-packages/flask_script/__init__.py",line 417, in run
result = self.handle(argv[0], argv[1:])
File"/home/jjw/.local/virtualenvs/flask/local/lib/python2.7/site-packages/flask_script/__init__.py",line 386, in handle
。。。。。。
File "
File"/home/jjw/.local/virtualenvs/flask/local/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",line 3112, in format_constraint
return self.quote(constraint.name)
File"/home/jjw/.local/virtualenvs/flask/local/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",line 3062, in quote
if self._requires_quotes(ident):
File"/home/jjw/.local/virtualenvs/flask/local/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",line 3033, in _requires_quotes
lc_value = value.lower()
AttributeError:'NoneType' object has no attribute 'lower'
我的模型的中的类为:
class Demo(db.Model):
__tablename__ = "demo"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32),unique=True)
#name2 = db.Column(db.String(32),unique=True) #version2中有此字段
password =db.Column(db.String(64))
#password2 =db.Column(db.String(64))
后来经过仔细研究看源码发现原来问题出在这里(在执行python 文件名.py db upgrade后会出现一个叫versions的文件夹打开最近生成的那个即可看到有downgrade然后修改里边的内容如下图)
当我第一次只添加一个password2字段然后执行migrate和upgrade后执行历史回退这个并没有发现有啥错误
class Demo(db.Model):
__tablename__ = "demo"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32),unique=True)
password =db.Column(db.String(64))
password2= db.Column(db.String(64))
但是当我再重新写一个demo把之前的name2字段添加上去的时候即:
class Demo(db.Model):
__tablename__ = "demo"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32),unique=True)
name2 = db.Column(db.String(32),unique=True)
password =db.Column(db.String(64))
password2 =db.Column(db.String(64))
这时执行migrate和upgrade之后再回退却报错了报了上边的异常后来经过分析源码发现问题是这样的这个unique约束有问题这应该是一个版本的问题,它并没有将我要回退的版本中的那个字段给写到那个downgrade中可以修改如下图(name2这个字段):修改完后在执行回退命令就成功了但这样做有点麻烦后来发现还可以这样做如下图:
convention = {
"ix": 'ix_%(column_0_label)s',
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s"
}
metadata = MetaData(naming_convention=convention)
db = SQLAlchemy(app, metadata=metadata)
这个db = SQLAlchemy(app, metadata=metadata)是在原来的基础上(db=SQLAlchemy(app))添加了metadata=metadata这个字段后的,然后执行回退操作就会成功