简体   繁体   English

如何在sqlite alembic迁移中迁移数据?

[英]How to migrate data in sqlite alembic migration?

I have a column goods.visible (boolean) and i want to replace it with goods.status (enum). 我有一个列goods.visible (布尔值),我想用goods.status (枚举)替换它。

I need to replace one column with another and migrate data using sqlalchemy (to use its data type conversion mechanism). 我需要用另一列替换一列并使用sqlalchemy迁移数据(以使用其数据类型转换机制)。 As sqlite does not support ALTER TABLE for this, I have to use batch_alter_table alembic operation for this. 由于sqlite不支持ALTER TABLE,我必须使用batch_alter_table alembic操作。

My migration looks like the following. 我的迁移如下所示。 It throws sqlite3.OperationalError: no such column: goods.status , because in my old table there is no such column (new table is created for migration using batch) 它抛出了sqlite3.OperationalError: no such column: goods.status ,因为在我的旧表中没有这样的列(使用批处理创建新表)

def upgrade():
    with op.batch_alter_table('goods') as batch_op:
        batch_op.add_column(sa.Column('status', sa.Enum('published', 'unpublished', 'deleted'), nullable=True))

        conn = op.get_bind()
        Session = sa.orm.sessionmaker()
        session = Session(bind=conn)
        for good in session.query(Good):
            # I want to perform some data updates & insert data into new column
        batch_op.drop_column('visible')

If i will add load_only to specify columns to be selected from the table: sqlite3.OperationalError: no such column: goods.status 如果我将添加load_only以指定要从表中选择的列: sqlite3.OperationalError: no such column: goods.status

i will get error sqlalchemy.exc.ArgumentError: Can't find property named 'visible' on the mapped entity Mapper|Good|goods in this Query. 我将得到错误sqlalchemy.exc.ArgumentError: Can't find property named 'visible' on the mapped entity Mapper|Good|goods in this Query. . I understand why i get it - i have no more property visible in my model. 我理解为什么我得到它 - 我的模型中没有更多属性可见。

How i can migrate data using alembic in this case? 在这种情况下,如何使用alembic迁移数据?

I tried to use raw queries.. but it says there is no table: 我试图使用原始查询..但它说没有表:

    s = sa.sql.select([sa.sql.text('goods.*')])
    for row in conn.execute(s):
        print(row)

Hovewer inspector displays goods table: Hovewer检查员显示goods表:

 inspector = sa.inspect(conn.engine)
    for table_name in inspector.get_table_names():
        print(table_name)
        for column in inspector.get_columns(table_name):
            print("Column: %s" % column['name'])

Displays 显示器

goods
Column: id
Column: name
Column: price
Column: visible

You can have multiple batch_alter_table blocks. 您可以拥有多个batch_alter_table块。 Use the first one to add the new column, then (outside and after the block) run your business logic (in this case conversion of your boolean value to some enum values), then use another block to drop the column. 使用第一个添加新列,然后(在块之外和之后)运行业务逻辑(在这种情况下,将布尔值转换为某些枚举值),然后使用另一个块删除列。

Something like:- 就像是:-

def upgrade():
    with op.batch_alter_table('goods') as batch_op:
        batch_op.add_column(sa.Column('status', sa.Enum('published', 'unpublished', 'deleted'), nullable=True))
    # Do your business logic here
    with op.batch_alter_table('goods') as batch_op:
        batch_op.drop_column('visible')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM