用psycopg2 mogrify并返回

时间:2015-12-28 14:01:28

标签: python postgresql psycopg2

我试图生成自动查询。我在想使用executemany,但我需要使用return语句,所以我做了:

def format_bind(cols, rows):
    return '(' + '), ('.join([', '.join(['%s'] * cols)] * rows) + ')'        

def insert_many(table, values, id_column):
                if not values:
                    return []

                keys = values[0].keys()
                conn = psycopg2.connect("dbname='db' user='postgres' host='localhost' password='postgres'")
            cursor = conn.cursor()
            query = cursor.mogrify("INSERT INTO {} ({}) VALUES {} RETURNING {}".format(table,
                                                                                         ', '.join(keys),
                                                                                         format_bind(len(keys), len(values)),
                                                                                         id_column),
                                   [tuple(v.values()) for v in values])
            cursor.execute(query)
            return [t[0] for t in (cursor.fetchall())]

问题是当我执行它时,我得到:error list index out of range任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:4)

问题是我认为我必须为要插入的每个值设置一个字符串参数插值。我会解释一下:

假设我有一个包含2个词典(长度为3个)的列表,其中包含要插入的数据:

lst = [{'a': 21, 'b': 9, 'c': 33}, {'a': 76, 'b': 84, 'c': 46}]

为了插入这些值,我做了类似的事情:

query = curs.mogrify("INSERT INTO {} ({}) VALUES {} RETURNING {}".format(
                        table,
                        ', '.join(lst[0].keys()),
                        ', '.join(['%s'] * len(lst[0].values())),
                        'id'
                    ), [tuple(v.values()) for v in lst])

总共添加三个'%s'lst中单个字典中的每个项目一个)。结果是异常消息 error list index out of range ,这是因为curs.mogrify()期待'%s'中每个字典只有一个lst ,所以对于这种情况,它只需要两个'%s'而不是三个。

因此,从lst插入数据的正确形式是:

query = curs.mogrify("INSERT INTO {} ({}) VALUES {} RETURNING {}".format(
                            table,
                            ', '.join(lst[0].keys()),
                            ', '.join(['%s'] * len(lst)),
                            'id'
                        ), [tuple(v.values()) for v in lst])

len(lst[0].values()) 取代 len(lst)

这是我如何解决我的问题(我不理解这一点,因为我没有正确阅读该示例的代码)。我希望这会有所帮助。

萨姆