gpt4 book ai didi

python - 使用内存缓冲区的 psycopg2 Postgres COPY EXPERT 到 Pandas read_csv 失败并出现 ValueError

转载 作者:太空宇宙 更新时间:2023-11-03 10:55:44 27 4
gpt4 key购买 nike

所以我使用 Python 3.5 中的 psycopg2 驱动程序运行以下代码到 Pandas 19.x。

 buf = io.StringIO()
cursor = conn.cursor()
sql_query = 'COPY ('+ base_sql + ' limit 100) TO STDOUT WITH CSV HEADER'
cursor.copy_expert(sql_query, buf)
df = pd.read_csv(buf.getvalue(),engine='c')
buf.close()

read_csv 在从内存缓冲区读取数据时会爆 block :

pandas\parser.pyx in pandas.parser.TextReader.__cinit__ (pandas\parser.c:4175)()

pandas\parser.pyx in pandas.parser.TextReader._setup_parser_source (pandas\parser.c:8333)()

C:\Users\....\AppData\Local\Continuum\Anaconda3\lib\genericpath.py in exists(path)
17 """Test whether a path exists. Returns False for broken symbolic links"""
18 try:
---> 19 os.stat(path)
20 except OSError:
21 return False

ValueError: stat: path too long for Windows

呃..什么路径? buf 在内存中。我在这里错过了什么?

仅供引用,复制到似乎按预期工作。

下面的解决方案代码

多亏了下面的答案,使用这种方法我的查询速度提高了一倍,我的内存使用率下降了 500%。这是我的最终测试代码,用于帮助其他人解决他们的性能问题。我很乐意看到任何改进它的代码!请务必在您的问题中链接回此问题。

# COPY TO CSV quick and dirty performance test
import io
import sys

start = time.time()
conn_str_copy= r'postgresql+psycopg2://' + user_id + r":" + pswd + r"@xxx.xxx.xxx.xxx:ppppp/my_database"
result = urlparse(conn_str_copy)
username = result.username
password = result.password
database = result.path[1:]
hostname = result.hostname

size = 2**30
buf = io.BytesIO()
# buf = io.StringIO()

engine = create_engine(conn_str_copy)
conn_copy= psycopg2.connect(
database=database, user=username, password=password, host=hostname)

cursor_copy = conn_copy.cursor()
sql_query = 'COPY ('+ my_sql_query + ' ) TO STDOUT WITH CSV HEADER'
cursor_copy.copy_expert(sql_query, buf, size)
print('time:', (time.time() - start)/60, 'minutes or ', time.time() - start, 'seconds')
tmp = buf.seek(0)
df = pd.read_csv(buf,engine='c', low_memory=False )
buf.close()
print('time:', (time.time() - start)/60, 'minutes or ', time.time() - start, 'seconds')

从 postgres 复制数据的速度约为 4 分钟,将其加载到 pandas 数据帧的速度不到 30 秒。请注意,复制命令是 psycopg2 驱动程序的一项功能,可能无法在其他驱动程序中使用。

最佳答案

您必须将文件句柄或文件名传递给 pandas.read_csv()

传递 buf.getvalue() 使 pandas read_csv 相信您传递的是文件名,因为对象没有 read 方法,除了“文件名”是缓冲区并且它被认为太长(Windows 限制文件名为 255 个字符)

你几乎明白了。由于 buf 已经是一个类文件对象,因此只需按原样传递即可。小细节:你必须倒带它,因为之前的 cursor.copy_expert(sql_query, buf) 调用可能使用了 write 并且 buf 位置在最后(尝试不使用它,您可能会得到一个空数据框)

buf.seek(0)  # rewind because you're at the end of the buffer
df = pd.read_csv(buf,engine='c')

关于python - 使用内存缓冲区的 psycopg2 Postgres COPY EXPERT 到 Pandas read_csv 失败并出现 ValueError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41249286/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com