我编写了一个python脚本来使用create table if not exists
语句创建表,然后将数据帧中的行插入到vertica数据库中。我第一次运行这个python脚本时,我希望它创建一个表并插入数据 - 它工作正常。
但是从下一次开始,我希望它只有在不存在时才能创建表(工作正常),并且只有在数据库中不包含该行时才插入数据。
我使用insert
语句和COPY
语句来插入数据。如何在python中执行此操作?我使用pyodbc从python访问Vertica数据库。
编辑帖子以包含一些代码: 有一个名为tableframe_df的数据框,我需要将内容填充到如下所示的表中:
我正在使用create table创建一个表,如果不存在,则创建一个表(如果没有表)。
cursor.execute("create table if not exists <tablename> (fields in the table)")
COPY statement to write to this table from a csv that was created
`cursor.execute("COPY tablename1 FROM LOCAL 'tablename.csv' DELIMITER ',' exceptions 'exceptions' rejected data 'rejected'")`
##for i,row in tablename_df.iterrows():
cursor.execute("insert into tablename2 values(?,?,?,?,?,?,?,?,?,?,?,?)",row.values[0],row.values[1],row.values[2],row.values[3],row.values[4],row.values[5],row.values[6],row.values[7],row.values[8],row.values[9],row.values[10],row.values[11])
在上面的代码中,我正在创建表,然后使用COPY和insert插入tablename1和tablename2。这在第一次执行时工作正常(因为表中没有数据)。现在错误地说,如果我运行两次相同的脚本,数据将在这些表中插入两次。 如果数据已经存在,我应该执行哪些检查以确保数据不会被插入?
答案 0 :(得分:1)
首先我要提一下,如果你要做很多行,INSERT VALUES
会很慢。如果您正在使用批处理sql和标准vertica驱动程序,它应该将其转换为COPY
,但如果没有,那么您的插入可能需要永久。我不认为pyodbc
会发生这种情况,因为它们没有最佳地实现executemany()
。您可以使用ceodbc
,但我还没有尝试过。或者,您可以使用具有vertica_python
命令效率的.copy('COPY FROM STDIN...',data)
。
无论如何,对于你的问题......
你可以通过以下两种方式之一做到这一点。同样对于插入,我真的会尝试将其更改为副本或至少executemany
。同样,pydobc
不能正确地执行此操作,至少对于我使用的版本而言。
使用一个控制表,以某种方式唯一地描述正在加载的数据集并插入其中,并在运行脚本之前检查数据集是否尚未加载。
- 步骤1.检查控制表的数据集负载。
SELECT *
FROM mycontroltable
WHERE dataset = ?
- 步骤2.如果找不到行,请插入行
for row in data:
cursor.execute('INSERT INTO mytargettable....VALUES(...)')
- 步骤3.将行插入控制表
INSERT INTO mycontroltable( dataset ) VALUES ( ? )
- 步骤4.提交数据
COMMIT
或者,您可以根据键插入或合并数据。您可以创建临时表或其他临时表来执行此操作。如果您不想更新并且数据一旦插入就不会更改,那么INSERT会更好,因为它不会产生删除向量。我会INSERT
根据你提出的问题的方式做。{/ p>
- 步骤1.为中间目标创建本地临时值
CREATE LOCAL TEMP TABLE mytemp (fields) ON COMMIT DELETE ROWS;
- 步骤2.插入数据。
for row in data:
cursor.execute('INSERT INTO mytemp....VALUES(...)')
- 步骤3.仅按键值插入/选择不存在的数据
INSERT INTO mytargettable (fields)
SELECT fields
FROM mytemp
WHERE NOT EXISTS (
SELECT 1
FROM mytargettable t
WHERE t.key = mytemp.key
)
- 步骤4.提交
COMMIT;