psycopg2: insert multiple rows with one query

后端 未结 15 2289
谎友^
谎友^ 2020-11-22 09:11

I need to insert multiple rows with one query (number of rows is not constant), so I need to execute query like this one:

INSERT INTO t (a, b) VALUES (1, 2),         


        
15条回答
  •  情深已故
    2020-11-22 10:02

    Update with psycopg2 2.7:

    The classic executemany() is about 60 times slower than @ant32 's implementation (called "folded") as explained in this thread: https://www.postgresql.org/message-id/20170130215151.GA7081%40deb76.aryehleib.com

    This implementation was added to psycopg2 in version 2.7 and is called execute_values():

    from psycopg2.extras import execute_values
    execute_values(cur,
        "INSERT INTO test (id, v1, v2) VALUES %s",
        [(1, 2, 3), (4, 5, 6), (7, 8, 9)])
    

    Previous Answer:

    To insert multiple rows, using the multirow VALUES syntax with execute() is about 10x faster than using psycopg2 executemany(). Indeed, executemany() just runs many individual INSERT statements.

    @ant32 's code works perfectly in Python 2. But in Python 3, cursor.mogrify() returns bytes, cursor.execute() takes either bytes or strings, and ','.join() expects str instance.

    So in Python 3 you may need to modify @ant32 's code, by adding .decode('utf-8'):

    args_str = ','.join(cur.mogrify("(%s,%s,%s,%s,%s,%s,%s,%s,%s)", x).decode('utf-8') for x in tup)
    cur.execute("INSERT INTO table VALUES " + args_str)
    

    Or by using bytes (with b'' or b"") only:

    args_bytes = b','.join(cur.mogrify("(%s,%s,%s,%s,%s,%s,%s,%s,%s)", x) for x in tup)
    cur.execute(b"INSERT INTO table VALUES " + args_bytes) 
    

提交回复
热议问题