tan*_*bog 3 python postgresql psycopg2 xml-parsing python-3.x
我需要打开许多 XML 文件,然后进行处理以生成大量行,然后将这些行插入到远程 Postgress 数据库中的多个表中。
为了提取 XML 数据,我使用它xml.etree.ElementTree来解析 XML 树并根据需要提取元素。当我做很多事情时,基本操作是获取特定元素(无论是字符串还是整数)并将其放入多个字典之一中。
经过更多处理后,我需要将许多字典插入到数据库中。对于任何单个 xml 文件,我可能会在 3 个表中生成最多 8-10,000 行(或查询)。
在测试时,我输出到 sql 文件,然后手动运行查询。如果我有很多 xml 文件,这显然是行不通的。
因此,我尝试使用psycopg2自动化这个过程。据我了解,从堆栈溢出和其他地方运行单个execute 函数的速度非常慢。基于此 stackoverflow 问题,我尝试编写如下代码:
QueryData = ','.join(cur.mogrify('(%s,%s,%s)', row) for row in myData)
cur.execute('INSERT INTO DBTABLE' + QueryData)
cur.commit()
Run Code Online (Sandbox Code Playgroud)
其中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
Run Code Online (Sandbox Code Playgroud)
我的做法是完全错误的吗?我怎样才能做我需要的事情?我正在使用Python3。
额外的
我被要求展示一个数据示例。
这是最简单的,将 3 个整数值放入一个表中。它的形式如下:(document_id,item_index,item_code)
一个典型的例子是:(937, 138, 681)
我一般的转换尝试是尝试:
(str(document_id),str(item_index),str(item_code))
Run Code Online (Sandbox Code Playgroud)
我也尝试过另一种方式:
(bytes(document_id,'utf-8'),bytes(item_index,'utf-8'),bytes(item_code,'utf-8'))
Run Code Online (Sandbox Code Playgroud)
后者也会引发错误:TypeError: encoding without a string argument
psycopg文档指出对于 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)
Run Code Online (Sandbox Code Playgroud)
然而,正如StackOverflow 问题中提到的,复制大量数据的最有效方法是使用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')]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1981 次 |
| 最近记录: |