合并文件写入和读取

Consolidate file write and read together

我正在编写一个 python 脚本来将数据写入 Vertica 数据库。我用的是官方库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),先读取文件然后执行 "COPY from 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 很慢,那同样会有帮助!

谢谢!

首先,是的,先将数据写入文件是推荐的方式,也是最有效的方式。乍一看似乎效率低下,但将数据写入磁盘上的文件几乎不需要任何时间,但 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.

你可以用pip安装vertica_python

$ pip install vertica_python

$ pip3 install vertica_python

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

您也可以从 Vertica 的 GitHub 页面上的源代码构建 https://github.com/vertica/vertica-python/

至于将 COPY 命令与 vertica_python 一起使用,请在此处查看此问题的答案:

我已经使用了几个 python 库来连接到 Vertica,vertica_python 是目前为止我最喜欢的,自从 Vertica 从 Uber 接管开发以来,它一直在不断改进基础。