我有一个烧瓶应用程序,它使用Flask-SQLAlchemy来访问mysql。现在我想在同一个应用程序中重构数据模型,所以我创建了一个新的版本模型文件,但是一些表应该与旧表具有相同的名称。
oldmodel.py
class TableA(db.Model):
__tablename__ = 'TableA'
...
newmodel.py
class TableA(db.Model):
__tablename__ = 'TableA'
...
我写了一个函数,想法是通过旧的MetaData查询数据,然后在一些列数据操作后通过新的MetaData写入新的数据库,但它显然会在Flask-SQLAlchemy中报告相同的表名冲突。
错误信息是
sqlalchemy.exc.InvalidRequestError: Table 'TableA' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
我不想在旧数据库上使用Flask-migrate,而是要创建新数据库。
我也试过__bind_key__
,它似乎在一个新表中工作,但没有在已有数据的存在表中工作。
是否可以避免在同一个应用中使用两个版本的DataModel?或其他方法?
答案 0 :(得分:1)
最后,我找到了一种方法,将模型改为纯sqlalchemy风格,如
oldmodel.py
from sqlalchemy.ext.declarative import declarative_base
BaseOld = declarative_base()
class TableA(BaseOld):
__tablename__ = 'TableA'
newmodel.py
from sqlalchemy.ext.declarative import declarative_base
BaseNew = declarative_base()
class TableA(BaseNew):
__tablename__ = 'TableA'
然后使用相应的会话为不同的数据库创建两个引擎。 现在可以很容易地从旧数据库查询并根据需要写入新数据库。导入同名类时使用'从XXX导入XXX为XXX'以避免类名冲突。
另一种方法是,如果仍然使用flask-sqlalchemy的db.Model,则使用 bind_key 功能。它可以将Model类拆分为不同的数据库,但一个很大的限制是模型类名称不应该冲突。