2017-03-01 59 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