4

I need to migrate schema & data. I would like to organize it as described below. But sqlalchemy.Table requires Metadata object. Is it possible to retrieve it from alembic?

metadata = op.get_metadata() # how i can do this?

table = sa.Table('my_table', metadata, sa.Column('id',…), ...)

def upgrade():
    op.create_table(table)
    if context.get_x_argument(as_dictionary=True).get('data', None):
        data_upgrades()

def downgrade():
    if context.get_x_argument(as_dictionary=True).get('data', None):
        data_downgrades()
    op.drop_table(table)

def data_upgrades():
    op.bulk_insert(table, [ ... ])

def data_downgrades():
    table.delete()
bizi
  • 3,398
  • 2
  • 27
  • 28
avasin
  • 9,186
  • 18
  • 80
  • 127

1 Answers1

2

I was able to construct a new metadata object with the following:

 import alembic
 from sqlalchemy.schema import MetaData

 metadata = MetaData(bind=alembic.op.get_bind())

This should work. I'm not 100% sure whether the bind is really needed (depends on your use-case).

For older versions of alembic you may need to use the following line instead:

 metadata = MetaData(bind=alembic.context.get_context().bind)
exhuma
  • 20,071
  • 12
  • 90
  • 123
  • 1
    This works for me. With the version that I use (0.9.6), there is a shorter API to get the binding: `MetaData(bind=alembic.op.get_bind())`. – bizi May 21 '20 at 22:10
  • Does anybody know, is it the traget metadata or reflection of current database state? – Dmitry Aug 30 '22 at 09:57
  • 1
    @Dmitry: When doing the above, you create a completely *new* metadata instance. It's completely empty. If you want to reflect the objects from the DB you could fill it by using the "autoload" feature of SA. But if this is in an alembic migration you *should not do that*. If you have a more specific question, create a new post on here. Comments are not the right place for that. – exhuma Aug 31 '22 at 12:06