Python烧瓶 ​​- 迁移数据迁移未保存

时间:2016-03-17 12:45:17

标签: python flask migration

当我添加新列并从预先存在的列迁移数据时,会添加该列,但不会迁移数据(只保留列中的空值)。

from alembic import op  # NOQA
import sqlalchemy as sa  # NOQA
from pycoin.encoding import a2b_hashed_base58  # NOQA
from binascii import hexlify  # NOQA
from datetime import datetime, timedelta  # NOQA
from sqlalchemy.ext.declarative import declarative_base  # NOQA


Base = declarative_base()
Session = sa.orm.sessionmaker()


class Farmer(Base):
    __tablename__ = 'farmer'
    id = sa.Column(sa.Integer, primary_key=True)
    btc_addr = sa.Column(sa.String(35), unique=True)  # TODO migrate to nodeid


def upgrade():
    bind = op.get_bind()
    session = Session(bind=bind)
    op.add_column('farmer', sa.Column('nodeid', sa.String(length=40),
                                      nullable=True))
    for farmer in session.query(Farmer):
        nodeid = hexlify(a2b_hashed_base58(farmer.btc_addr)[1:])
        if isinstance(nodeid, bytes):
            nodeid = nodeid.decode("utf-8")
        farmer.nodeid = nodeid
        print("saved nodeid: {0}".format(nodeid))  # called
    session.commit()

编辑:

这个问题已得到正确回答,我创建了一个isolated example here来演示如何进行数据迁移,因为我无法在任何地方找到一个好的。

1 个答案:

答案 0 :(得分:0)

作为一般规则,在迁移脚本中使用ORM是一个坏主意。正如您已经经历过的那样,您必须做一些奇怪的事情以避免错误。很明显,你已经看到了这一点,因此决定在脚本本身中包含你的模型的副本。

您的解决方案存在的问题是,您复制的Farmer模型没有要迁移到的nodeid属性。如果您在迁移脚本中包含的模型副本中包含此属性,我认为您将能够执行数据迁移。

但无论如何,我认为在迁移中明确复制的模型可能会导致错误。我的建议是您不要使用ORM来迁移数据。如果在SQLAlchemy中使用较低级别的SQL生成支持,您仍然可以拥有非常体面的东西。您将创建一个临时Table实例,该实例表示数据库表在需要迁移的确切位置的状态,然后您可以在SQLAlchemy中发出SQL类以进行所需的更改。

有关包含数据迁移的示例迁移脚本结构,请参阅官方Alembic文档中的此示例:http://alembic.readthedocs.org/en/latest/cookbook.html#conditional-migration-elements

有关实现与您类似的数据迁移脚本的示例,请参阅https://julo.ch/blog/migrating-content-with-alembic/