【问题标题】:Insert into Vertica if table does not exist or not a duplicate row如果表不存在或不是重复行,则插入 Vertica
【发布时间】:2015-10-20 23:28:09
【问题描述】:

我编写了一个 python 脚本来使用 create table if not exists 语句创建一个表,然后将数据帧中的行插入到 vertica 数据库中。当我第一次运行这个 python 脚本时,我希望它创建一个表并插入数据——它工作正常。

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

我同时使用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 中。这在第一次执行时工作正常(因为表中没有数据)。现在如果我错误地运行相同的脚本两次,数据将在这些表中插入两次。 如果数据已经存在,我应该执行什么检查以确保不会插入数据?

【问题讨论】:

  • 您需要实际展示您需要帮助的 Python 代码。我们不会为您编写代码。
  • 不清楚你在问什么。具体来说,您想弄清楚如何在 Python 中做什么? COPY?或者 INSERT 仅当目标中不存在该行的数据时?还是两者兼而有之?
  • 我正在寻找两者,仅当目标中不存在该行的数据时复制或插入。正如@kermit 所问,我将包含我正在寻找的代码
  • “如果数据已经存在,我应该执行什么检查以确保不会插入数据?” 加载到临时表并使用NOT EXISTS 或@987654328 @
  • 当然。我的费率是 130 美元/小时。

标签: python pandas insert vertica


【解决方案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(...)')
    

    -- Step 3. 向控制表中插入行

    INSERT INTO mycontroltable( dataset ) VALUES ( ? )
    

    -- Step 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;
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-22
    • 2019-10-17
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2014-01-22
    相关资源
    最近更新 更多