2015-10-20 19 views
0

我写了一个python脚本使用create table if not exists语句创建一个表,然后插入来自数据帧行到Vertica的数据库。我第一次运行这个python脚本时,我希望它创建一个表并插入数据 - 它工作正常。插入Vertica的,如果表不存在或不是一个重复的行

但是从开始下一次,我希望它创建一个表只有当不存在(正常工作)且仅当该行没有在数据库中包含的数据插入它。

我同时使用insert声明,COPY语句来插入数据。如何在Python中做到这一点?我正在使用pyodbc从python访问Vertica数据库。

编辑的帖子,包括一些代码: 有一个名为tableframe_df数据框,从中我需要填充内容到作为波纹管创建一个表:

我在Vertica的创建表创建表如果不存在,则创建一个表,如果没有的话。

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和插入插入到tablename1和tablename2中。这在第一次执行时工作正常(因为表中没有数据)。现在,如果我运行同一个脚本两次,那么数据将在这些表中插入两次。 我应该执行什么检查以确保数据在已经存在的情况下不会被插入?

+0

您需要实际显示您需要帮助的Python代码。我们不会为您编写代码。 – Kermit

+0

目前还不清楚你在问什么。特别是你想弄清楚如何在Python中做什么? 'COPY'?或者只有当该行的数据不存在于目标中时才使用INSERT?或两者? – woot

+0

我正在寻找这两个,COPY或插入仅当该行的数据不存在于目标中。正如@kermit所问,我将包含我正在寻找的代码 –

回答

1

首先,我将提及INSERT VALUES是相当缓慢的,如果你做了很多行。如果您使用的是批量sql和标准vertica驱动程序,它应该将其转换为COPY,但如果不是这样,那么您的插入操作可能会花费很长时间。我认为这种情况不会发生在pyodbc之后,因为他们没有最佳地实施executemany()。尽管你可能可以使用ceodbc,但我还没有尝试过。或者,您可以使用vertica_python,该命令有效地使用了.copy('COPY FROM STDIN...',data)命令。

总之,你的问题......

你可以做的是两种方式之一。也为插入,我真的会尝试将其更改为副本或至少一个executemany。再次,pydobc不正确地做到这一点,至少对于我使用过的版本来说。

  1. 使用,不知怎的,唯一描述这组数据被加载并插入到它,并运行该数据集尚未加载脚本之前检查控制表。对于数据集负载

    --step 1.检查控制表。

    SELECT * 
    FROM mycontroltable 
    WHERE dataset = ? 
    

    --step 2.如果未找到行,插入行

    for row in data: 
        cursor.execute('INSERT INTO mytargettable....VALUES(...)') 
    

    - 步骤3中插入行控制表

    INSERT INTO mycontroltable(dataset) VALUES (?) 
    

    - 步骤4。提交数据

    COMMIT 
    
  2. 或者,您可以基于密钥插入或合并数据。您可以创建临时表或其他临时表来执行此操作。如果你不想更新,并且插入后数据不会改变,那么INSERT会更好,因为它不会产生删除向量。我会根据你说的问题的方式做INSERT

    --step 1.一种用于中间目标

    CREATE LOCAL TEMP TABLE mytemp (fields) ON COMMIT DELETE ROWS; 
    

    --step 2.将数据创建本地临时。

    for row in data: 
        cursor.execute('INSERT INTO mytemp....VALUES(...)') 
    

    --step 3.插入/只选择不通过键值存在数据

    INSERT INTO mytargettable (fields) 
    SELECT fields 
    FROM mytemp 
    WHERE NOT EXISTS (
        SELECT 1 
        FROM mytargettable t 
        WHERE t.key = mytemp.key 
    ) 
    

    --step 4.提交

    COMMIT; 
    
相关问题