问题1 of 2
我尝试使用Uber的vertica-python软件包使用Python将数据从CSV文件导入Vertica。问题是只有空格的数据元素被加载到Vertica中作为NULL;我想只将空数据元素作为NULL加载,而非空白色空格数据元素作为空格加载。
例如,以下两行CSV文件都作为(' 1',' abc',NULL,NULL)加载到数据库中,而我想要第二行一个要加载(' 1',' abc','',NULL)。
1,abc,,^M
1,abc, ,^M
以下是代码:
# import vertica-python package by Uber
# source: https://github.com/uber/vertica-python
import vertica_python
# write CSV file
filename = 'temp.csv'
data = <list of lists, e.g. [[1,'abc',None,'def'],[2,'b','c','d']]>
with open(filename, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f, escapechar='\\', doublequote=False)
writer.writerows(data)
# define query
q = "copy <table_name> (<column_names>) from stdin "\
"delimiter ',' "\
"enclosed by '\"' "\
"record terminator E'\\r' "
# copy data
conn = vertica_python.connect( host=<host>,
port=<port>,
user=<user>,
password=<password>,
database=<database>,
charset='utf8' )
cur = conn.cursor()
with open(filename, 'rb') as f:
cur.copy(q, f)
conn.close()
问题2 of 2
是否还有其他问题(例如字符编码)我需要注意使用这种将数据加载到Vertica的方法?代码中是否还有其他错误?我并非100%确信它可以在所有平台上运行(目前在Linux上运行;例如,在其他平台上可能存在记录终结器问题)。任何使这些代码更加健壮的建议都将非常受欢迎。
此外,还有其他方法可以从Python中将数据批量插入Vertica,例如直接从Python加载对象而不必先将它们写入CSV文件,而不会牺牲速度吗?数据量很大,插入作业需要几个小时才能运行。
提前感谢您提供任何帮助!
答案 0 :(得分:1)
您拥有的复制声明应该按照您想要的方式执行空格。我使用非常相似的COPY
测试了它。
编辑:我错过了你真正要求的副本,我会留下这部分,因为它可能对某些人有用:
要修复空白,您可以更改复制声明:
copy <table_name> (FIELD1, FIELD2, MYFIELD3 AS FILLER VARCHAR(50), FIELD4, FIELD3 AS NVL(MYFIELD3,'') ) from stdin
通过使用填充符,它会将其解析为类似变量的变量,然后您可以在副本中使用AS
将其分配给实际的表字段。
至于任何陷阱......我经常在Solaris上做你所拥有的。我注意到的唯一一件事就是你正在设置记录终止符,不确定这是否真的是你需要做的事情,具体取决于环境。我从来没有必要在linux,windows和solaris之间进行切换。
另外,一个提示,这将返回一个结果集,它将告诉您已加载了多少行。做一个fetchone()
并打印出来然后你会看到它。
我可以推荐的唯一另一件事可能是在任何行拒绝的情况下使用拒绝表。
你提到这是一项大工作。您可能需要通过向连接添加'read_timeout': 7200,
或更多来增加读取超时。我不确定None是否会禁用读取超时。
至于更快的方式...如果文件可以直接在vertica节点上访问,你可以直接在副本中引用文件,而不是执行copy from stdin
并让守护进程直接加载它。它速度更快,并且可以进行大量优化。然后,您可以使用分摊加载,如果要加载多个文件,则可以在文件列表中一起引用它们。
但这是一个很长的话题。如果您有任何具体问题,请告诉我。