用于批量插入的psycopg2格式

时间:2015-07-06 18:10:55

标签: python postgresql psycopg2

我以这种方式插入行,data是多个fieldname: fieldvalue项的字典:

def add_row(self, data, table): #data is a dictionary
    columns = data.keys()
    values = []

    for column in columns:
        if isinstance(data[column], list): #checking for json values
            values.append(Json(data[column])) 
        elif isinstance(data[column], dict):
            values.append(Json(data[column])) 
        else:
            values.append(data[column])
    insert_statement = 'insert into %s ' % table + '(%s) values %s'
    self.cur.execute(insert_statement, (AsIs(','.join(columns)), tuple(values)))
    self.conn.commit()
    print "added %s" % table

但是现在我想批量插入行以提高性能并减少I / O使用。问题是我找不到正确的方法。以下函数抛出(data是上述项目的列表):

psycopg2.ProgrammingError: syntax error at or near "["
LINE 1: ...,category_id,initial_quantity,base_price) VALUES ([u'Entrega...
def add_row_bulk(self, data, table): #data is a dictionary
    columns = data[0].keys()
    value_rows = []
    for e in data:
        columns = e.keys()
        values = []

        for column in columns:
            if isinstance(e[column], list): #checking for json values
                values.append(Json(e[column])) 
            elif isinstance(e[column], dict):
                values.append(Json(e[column])) 
            else:
                values.append(e[column])
        value_rows.append(AsIs(values))

    cols = (AsIs(','.join(columns)))
    query = self.cur.mogrify("INSERT INTO item (%s) VALUES %s", (cols, tuple(value_rows)))
    self.cur.execute(query) 
    self.conn.commit()
    print "added %s" % table

1 个答案:

答案 0 :(得分:2)

您的SQL生成代码存在一些问题。

首先,AsIs(values)不会mogrify进入值行,就像您似乎希望的那样。测试它,似乎等同于AsIs(str(values))。这是你在抛出的错误中看到的输出。

在您的工作示例中有用的是在单独的值元组上使用mogrify。将tuple(values)添加到value_rows,而不是AsIs(values)

其次,要指定在一个insert语句中插入多个行的值,您需要SQL syntax similar to the following

... VALUES (1, 'x'), (2, 'y'), (3, 'z')

请注意,值列表列表周围没有( )。什么都没有(我知道),奇怪的是mogrify进入这样的列表。当然tuple不会。

所以你需要做一些事情:

self.cur.mogrify('INSERT INTO item (%s) VALUES %s,%s,%s,%s',
                 (cols, value_row1, value_row2, value_row3, value_row4))

这意味着你需要做更多的工作来生成mogrify的两个参数,因为事先不知道行数。要生成第一个参数,您可以执行以下操作:

'INSERT INTO item (%s) VALUES ' + ','.join(['%s'] * len(value_rows))

第二个参数必须是第一个值为cols的序列,其余为value_rows的内容。一种方法:

[cols] + value_rows