如何使用alembic / SQLAlchemy将表对象实例化为bulk_insert行

时间:2018-05-31 14:40:50

标签: python sqlalchemy database-migration alembic

我正在尝试使用bulk_insert将数据插入Postgres数据库中的现有表(services)。如何实例化此表对象,以便我可以使用它执行bulk_insert?

我看到这样的答案: Alembic bulk_insert to table with schema但我希望避免在迁移中再次重新定义架构。

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql


def upgrade():
    """Up migration."""


services = sa.MetaData().Services()

op.bulk_insert(services,
    [   
        {
        'id': 88,
        'name':'Test 1',
        'is_active': 'true',
        'include_in_broker_fee': 'true',
        'is_domestic': 'true',
        'is_international': 'true'
        },
        {
        'id': 89,
        'name':'Test 2',
        'is_active': 'true',
        'include_in_broker_fee': 'true',
        'is_domestic': 'true',
        'is_international': 'true'
        }
   ])

3 个答案:

答案 0 :(得分:4)

如上所示,为了更新表格,您需要定义它,以便sqlalchemy知道要更新的内容。使用炼金术的MetaData()对象这样做非常简单,事实上你几乎拥有它。尝试这样的事情:

    from sqlalchemy import Table, MetaData

    meta = MetaData(bind=op.get_bind())
    services = Table('services', meta)

现在已经定义了表格,您可以利用炼金术的批量更新方法。为此,我向您介绍他们的文档,其中显示了bulk_insert_mappings()和bulk_save_objects()的几个示例--- http://docs.sqlalchemy.org/en/latest/faq/performance.html

答案 1 :(得分:2)

以防有人像我一样偶然发现此问题:当前,要使此工作正常,您需要在MetaData()对象中反映特定的表。基础数据库是MySQL。

工作代码:

from alembic import op
from sqlalchemy import Table, MetaData

def upgrade():

    # get metadata from current connection
    meta = MetaData(bind=op.get_bind())

    # pass in tuple with tables we want to reflect, otherwise whole database will get reflected
    meta.reflect(only=('some_table',))

    # define table representation
    some_table_tbl = Table('some_table', meta)

    # insert records
    op.bulk_insert(
        some_table_tbl,
        [
            {
                # data here...
            },  # (...)
        ]

答案 2 :(得分:0)

如果将表作为代码模型,还可以使用__table__属性:

from src.models.services import Service

op.bulk_insert(Service.__table__,
    [   
        {
        'id': 88,
        'name':'Test 1',
        'is_active': 'true',
        'include_in_broker_fee': 'true',
        'is_domestic': 'true',
        'is_international': 'true'
        },
        {
        'id': 89,
        'name':'Test 2',
        'is_active': 'true',
        'include_in_broker_fee': 'true',
        'is_domestic': 'true',
        'is_international': 'true'
        }
   ])