使用psycopg2将许多行插入到postgreSQL中的错误

时间:2016-09-24 03:10:48

标签: python postgresql python-3.x xml-parsing psycopg2

我需要打开一些XML文件,然后进行处理以生成大量行,然后将这些行插入远程postgress数据库中的多个表中。

要提取XML数据,我使用xml.etree.ElementTree来解析XML树并根据需要提取元素。虽然我正在做很多事情,但基本的操作是采用一个特定的元素,无论是字符串还是整数,并放在一些字典中。

经过一些处理之后,我需要将一些字典插入到我的数据库中。对于任何单个xml文件,我可以在3个表中生成最多8-10,000行(或查询)。

在测试时,我输出到sql文件,然后手动运行查询。如果我有很多xml文件,那显然不会起作用..

因此我尝试使用psycopg2来自动完成此过程。据我了解,从堆栈溢出和其他地方运行单个execute函数是非常缓慢的。基于This stackoverflow question,我试图编写如下代码:

QueryData = ','.join(cur.mogrify('(%s,%s,%s)', row) for row in myData)
cur.execute('INSERT INTO DBTABLE' + QueryData)
cur.commit()

其中myData是元组[(a,b,c),(a,b,c),(a,b,c)...]的列表,其内容是xml.etree.ElementTree提取的数据和我自己计算的值的组合。

当我尝试实际执行上面的代码时,我收到以下错误:

TypeError: sequence item 0: expected str instance, bytes found

好的......如果我然后尝试将我的数据(每个元组元素)转换为str()但是我得到了:

TypeError: encoding without a string argument

我是否只是完全错了?我该怎么做我需要的东西?我正在使用Python3。

其他

我被要求展示数据的一个例子。

这是最简单的,它是3个整数值放入表中。它的格式为:(document_id,item_index,item_code)

一个典型的例子是:(937, 138, 681)

我转换的一般尝试是尝试:

(str(document_id),str(item_index),str(item_code))

我也尝试过另一种方式:

(bytes(document_id,'utf-8'),bytes(item_index,'utf-8'),bytes(item_code,'utf-8'))

后者也会引发错误:TypeError: encoding without a string argument

3 个答案:

答案 0 :(得分:2)

psycopg documentation表示对于cur.mogrify:

  

返回的字符串始终是字节字符串。

所以要使用这个hack,你只需要将mogrify的结果解码回字符串,例如:

QueryData = ','.join(cur.mogrify('(%s,%s,%s)', row).decode('utf-8') for row in myData)
cur.execute('INSERT INTO DBTABLE' + QueryData)

但是,如this StackOverflow question中所述,复制大量数据的最有效方法是使用COPY。您可以使用任何“类似python文件的对象”来完成此操作。以下是psycopg文档中的一个示例:

>>> f = StringIO("42\tfoo\n74\tbar\n")
>>> cur.copy_from(f, 'test', columns=('num', 'data'))
>>> cur.execute("select * from test where id > 5;")
>>> cur.fetchall()
[(6, 42, 'foo'), (7, 74, 'bar')]

答案 1 :(得分:0)

你在表名后丢失了VALUES,其他一切似乎都是正确的:

cursorPG.execute(“插入测试 VALUES ”+','。join(cursorPG.mogrify('(%s,%s)',x)for m in mydata))< / p>

答案 2 :(得分:0)

好的,所以我让它工作......但是我很困惑为什么我的解决方案有效。我发布它作为答案,但如果有人可以向我解释发生了什么将是伟大的:

基本上是这样的:

QueryData = ','.join(cur.mogrify('(%s,%s,%s)', row) for row in myData)
cur.execute('INSERT INTO DBTABLE' + QueryData)

必须改为:

QueryData = b','.join(cur.mogrify(b'(%s,%s,%s)', row) for row in myData)
cur.execute(b'INSERT INTO DBTABLE' + QueryData)

这让我觉得非常不优雅。