2015-10-20 79 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; 
    
相關問題