psycopg2: вставка нескольких строк одним запросом - PullRequest
114 голосов
/ 15 ноября 2011

Мне нужно вставить несколько строк одним запросом (количество строк не является постоянным), поэтому мне нужно выполнить запрос, подобный этому:

INSERT INTO t (a, b) VALUES (1, 2), (3, 4), (5, 6);

Единственный способ, которым я знаю, это

args = [(1,2), (3,4), (5,6)]
args_str = ','.join(cursor.mogrify("%s", (x, )) for x in args)
cursor.execute("INSERT INTO t (a, b) VALUES "+args_str)

но я хочу какой-нибудь более простой способ.

Ответы [ 13 ]

0 голосов
/ 27 апреля 2016

Если вы используете SQLAlchemy, вам не нужно возиться с ручной обработкой строки, потому что SQLAlchemy поддерживает создание многострочного предложения VALUES для одного оператора INSERT :

rows = []
for i, name in enumerate(rawdata):
    row = {
        'id': i,
        'name': name,
        'valid': True,
    }
    rows.append(row)
if len(rows) > 0:  # INSERT fails if no rows
    insert_query = SQLAlchemyModelName.__table__.insert().values(rows)
    session.execute(insert_query)
0 голосов
/ 16 ноября 2015

Если вы хотите вставить несколько строк в одну вставку государственных операторов (при условии, что вы не используете ORM), то для меня проще всего было бы использовать список словарей.Вот пример:

 t = [{'id':1, 'start_date': '2015-07-19 00:00:00', 'end_date': '2015-07-20 00:00:00', 'campaignid': 6},
      {'id':2, 'start_date': '2015-07-19 00:00:00', 'end_date': '2015-07-20 00:00:00', 'campaignid': 7},
      {'id':3, 'start_date': '2015-07-19 00:00:00', 'end_date': '2015-07-20 00:00:00', 'campaignid': 8}]

conn.execute("insert into campaign_dates
             (id, start_date, end_date, campaignid) 
              values (%(id)s, %(start_date)s, %(end_date)s, %(campaignid)s);",
             t)

Как видите, будет выполнен только один запрос:

INFO sqlalchemy.engine.base.Engine insert into campaign_dates (id, start_date, end_date, campaignid) values (%(id)s, %(start_date)s, %(end_date)s, %(campaignid)s);
INFO sqlalchemy.engine.base.Engine [{'campaignid': 6, 'id': 1, 'end_date': '2015-07-20 00:00:00', 'start_date': '2015-07-19 00:00:00'}, {'campaignid': 7, 'id': 2, 'end_date': '2015-07-20 00:00:00', 'start_date': '2015-07-19 00:00:00'}, {'campaignid': 8, 'id': 3, 'end_date': '2015-07-20 00:00:00', 'start_date': '2015-07-19 00:00:00'}]
INFO sqlalchemy.engine.base.Engine COMMIT
0 голосов
/ 16 июля 2015

Использование aiopg - нижеприведенный фрагмент отлично работает

    # items = [10, 11, 12, 13]
    # group = 1
    tup = [(gid, pid) for pid in items]
    args_str = ",".join([str(s) for s in tup])
    # insert into group values (1, 10), (1, 11), (1, 12), (1, 13)
    yield from cur.execute("INSERT INTO group VALUES " + args_str)
...