2017-03-01 58 views
0

我試圖使用NULLIF函數通過psycopg2過濾INSERT INTO命令中的一些空條目。使用NULLIF與Psycopg2類型錯誤

問題是,如果列期望數字,它將無法正常工作,因爲NULLIF函數似乎被解釋爲文本。

我的表包含5列:

cursor.execute(CREATE TABLE myDb.myTable (id serial PRIMARY KEY, name varchar, value_min decimal, value_max decimal, action_name varchar, nb_solutions integer);") 

我使用插入從一個字符串數組一些數據:

cursor.executemany("INSERT INTO myDb.myTable (name, value_min, value_max, action_name, nb_solutions) VALUES (%s, %s, %s, NULLIF(%s,'None'), %s)", myArray[1:len(myArray)]) 

在這種情況下,NULLIF被正確地處理,並插入第四字符串% s從myArray或Null(取決於數組是否包含'None')。

但是,當我嘗試應用NULLIF到第5列,它是整數,NULLIF突然解釋爲文本:

cursor.executemany("INSERT INTO myDb.myTable (name, value_min, value_max, action_name, nb_solutions) VALUES (%s, %s, %s, %s, NULLIF(%s,'None'))", myArray[1:len(myArray)]) 

而且我得到以下錯誤:

ProgrammingError: column "nb_solutions" is of type integer but expression is of type text LINE 1: ...6085', ' 13.077', ' epsi', NULLIF(' 7...^HINT: You will need to rewrite or cast the expression. 
    args = ('column "nb_solutions" is of type integer but exp...You will need to rewrite or cast the expression.\n',) 
    cursor = <cursor object at 0x000000000578F3A8; closed: 0> 
    diag = <psycopg2.extensions.Diagnostics object> 
    pgcode = '42804' 
    pgerror = 'ERROR: column "nb_solutions" is of type integer...You will need to rewrite or cast the expression.\n' 
    with_traceback = <built-in method with_traceback of ProgrammingError object> Exported something to DB Mytable 

任何人都知道爲什麼發生這種情況?

回答

1

不要通過None作爲'None'字符串。通過真正的None價值和Psycopg將適應它正確。並且將它轉換爲預期的類型:

cursor.executemany(''' 
    INSERT INTO myDb.myTable (
     name, value_min, value_max, action_name, nb_solutions 
    ) VALUES (%s, %s, %s, %s, %s::int) 
''', myArray[1:len(myArray)]) 
+0

謝謝,但是,不能夠通過「真正的」'None'其實正是我之所以需要'NULLIF()'。我的數組來自Ajax post命令,在此期間數據被「串化」。這顯然不是整數的問題,它們被SQL正確讀取爲數字,但有時在整數中是一個未定義的值,它阻止了SQL命令。我認爲'nullif()'會幫助捕獲這些未定義的實例,並用'Null'替換它們來修復類型。我可以在SQL之前清理數據,但是會直接在查詢中使用'nullif()'。歡迎進一步的想法! – sc28

+0

所以,實際上我看起來有點像按照您的建議將數據轉換爲預期類型,並且通過將整個'nullif()'表達式轉換爲int(或'decimal')來解鎖查詢。非常感謝您發佈了一小段代碼,否則我不會想到這個訣竅!我最後的VALUES表達式是:(%s,NULLIF(%s,'None'):: decimal,NULLIF(%s,'None'):: decimal,%s,NULLIF(%s,'None'): :INT)' – sc28