如何使用 alembic / SQLAlchemy 实例化表对象以批量插入行

问题描述 投票:0回答:4

我正在尝试使用

bulk_insert
将数据插入到我的 Postgres 数据库中的现有表 (
services
) 中。如何实例化这个表对象,以便我可以用它进行批量插入?

我看到这样的答案: Alembicbulk_insert 到具有架构的表,但我想避免在迁移中再次重新定义架构。

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'
        }
   ])
python sqlalchemy database-migration alembic
4个回答
30
投票

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

12
投票

为了更新上面所示的表,您需要定义它,以便 sqlalchemy 知道要更新什么。使用 alchemy 的 MetaData() 对象执行此操作非常简单,事实上您几乎已经完成了。尝试这样的事情:

    from sqlalchemy import Table, MetaData

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

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


8
投票

如果您在代码中将表作为模型,您还可以使用

__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'
        }
   ])


0
投票

如果使用 SQLAlchemy 2.0 进行更新,根据文档“绑定数据”已删除,这基本上意味着如果使用本文前面推荐的方法,您的代码会略有不同。你只需要改变

from sqlalchemy import Table, MetaData

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

from sqlalchemy import Table, MetaData

meta = MetaData()
# reflect individual table
services = Table('services', meta, autoload_with=op.get_bind())
© www.soinside.com 2019 - 2024. All rights reserved.