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

How to instantiate a table object to bulk_insert rows using alembic / SQLAlchemy

我正在尝试使用 bulk_insert 将数据插入到我的 Postgres 数据库中现有的 table (services) 中。我如何实例化这个 table 对象以便我可以用它做一个 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'
        }
   ])

为了更新 table 如上所示,您需要对其进行定义,以便 sqlalchemy 知道要更新什么。使用 Alchemy 的 MetaData() 对象执行此操作非常简单,实际上您几乎已经做到了。尝试这样的事情:

    from sqlalchemy import Table, MetaData

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

现在 table 已定义,您可以利用 Alchemy 的批量更新方法。为此,我建议您参考他们的文档,其中显示了 bulk_insert_mappings() 和 bulk_save_objects() 的几个示例 --- http://docs.sqlalchemy.org/en/latest/faq/performance.html

万一有人像我一样偶然发现了这个问题:目前要使其正常工作,您需要在 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...
            },  # (...)
        ]

如果您将表格作为代码中的模型,您还可以使用 __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'
        }
   ])