合并文件读写

时间:2019-02-16 01:06:02

标签: python-2.7 vertica

我正在编写一个python脚本以将数据写入Vertica DB。我使用官方库vertica_db_client。出于某种原因,如果出于某种原因使用内置的cur.executemany方法,则需要很长时间才能完成(每1k条目需要40+秒)。我的建议是首先将数据保存到文件中,然后使用“ COPY”方法。这是保存到csv文件的部分:

with open('/data/dscp.csv', 'w') as out:
    csv_out=csv.writer(out)
    csv_out.writerow(("time_stamp", "subscriber", "ip_address", "remote_address", "signature_service_name", "dscp_out", "bytes_in", "bytes_out")) # which is for adding a title line
    for row in data:
        csv_out.writerow(row)

我的数据是元组列表。例子是:

[\
('2019-02-13 10:00:00', '09d5e206-daba-11e7-b122-00c03aaf89d2', '10.128.67.132', '10.135.3.11', 'SIP', 26, 2911, 4452), \
('2019-02-13 10:00:00', '09d5e206-daba-11e7-b122-00c03aaf89d2', '10.128.67.132', '10.135.3.21', 'SIP', 26, 4270, 5212), \
('2019-02-13 10:00:00', '09d5e206-daba-11e7-b122-00c03aaf89d2', '10.128.67.129', '18.215.140.51', 'HTTP2 over TLS', 0, 14378, 5291)\
]

然后,为了使用COPY方法,我必须(至少基于他们的指令https://www.vertica.com/docs/9.1.x/HTML/python_client/loadingdata_copystdin.html),首先读取文件,然后执行“从STDIN复制”。这是我的代码

f = open("/data/dscp.csv", "r")
cur.stdin = f
cur.execute("""COPY pason.dscp FROM STDIN DELIMITER ','""")

如果与问题无关,这里是连接数据库的代码

import vertica_db_client
user = 'dbadmin'
pwd = 'xxx'
database = 'xxx'
host = 'xxx'
db = vertica_db_client.connect(database=database, user=user, password=pwd, host=host)
cur = db.cursor()

因此,很明显,先保存然后阅读是浪费精力的。合并两个阅读部分的最佳方法是什么?

如果有人可以告诉我为什么我的execute.many太慢,那将同样有帮助!

谢谢!

1 个答案:

答案 0 :(得分:1)

首先,是的,这是建议的方法,也是将数据首先写入文件的最有效方法。乍一看似乎效率不高,但是将数据写入磁盘上的文件几乎几乎不需要时间,但是Vertica并未针对许多单独的INSERT语句进行优化。批量加载是将大量数据导入Vertica的最快方法。不仅如此,而且当您执行许多单独的INSERT语句时,您可能会遇到ROS推回问题,即使您不这样做,当在加载后合并ROS容器时,数据库上也会有额外的负载

您可以将元组数组转换为两个大字符串变量,然后将字符串打印到控制台。

字符串看起来像:

'2019-02-13 10:00:00', '09d5e206-daba-11e7-b122-00c03aaf89d2', '10.128.67.132', '10.135.3.11', 'SIP', 26, 2911, 4452
'2019-02-13 10:00:00', '09d5e206-daba-11e7-b122-00c03aaf89d2', '10.128.67.132', '10.135.3.21', 'SIP', 26, 4270, 5212
'2019-02-13 10:00:00', '09d5e206-daba-11e7-b122-00c03aaf89d2', '10.128.67.129', '18.215.140.51', 'HTTP2 over TLS', 0, 14378, 5291

但是您可以将其通过管道传递到VSQL命令中,而不是将其实际打印到控制台中。

$ python my_script.py | vsql -U dbadmin -d xxx -h xxx -c "COPY pason.dscp FROM STDIN DELIMITER ','"

这可能不是很有效。我在python中使用超长字符串变量没有太多经验。

第二,vertica_db_client不再由Vertica积极开发。尽管它至少在python2生命周期结束前仍将受支持,但您应该使用vertica_python

您可以通过点子安装vertica_python

$ pip install vertica_python

$ pip3 install vertica_python

取决于您要使用的Python版本。

您也可以在Vertica的GitHub页面https://github.com/vertica/vertica-python/中找到源代码进行构建

关于将COPY命令与vertica_python一起使用,请在此处查看此问题的答案:Import Data to SQL using Python

我已经使用了多个python库连接到Vertica,vertica_python到目前为止是我的最爱,自Vertica从Uber接手开发以来,它就一直在定期进行改进。