【问题标题】:Using NULLIF with Psycopg2 type error使用带有 Psycopg2 类型错误的 NULLIF
【发布时间】:2017-03-01 12:20:54
【问题描述】:

我正在尝试使用 NULLIF 函数通过 psycopg2 过滤掉 INSERT INTO 命令中的一些空条目。

问题是如果该列需要一个数字,它将不起作用,因为 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 被正确处理并插入来自 myArray 的第 4 个字符串 %s 或 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

有人知道为什么会这样吗?

【问题讨论】:

    标签: python postgresql types psycopg2 nullif


    【解决方案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)])
    

    【讨论】:

    • 谢谢,但是,不能通过“真实的”None 实际上正是我需要nullif() 的原因。我的数组来自 Ajax post 命令,在此期间数据被“字符串化”。这显然不是整数的问题,整数被 SQL 正确读取为数字,但有时整数中有一个未定义的值会阻止 SQL 命令。我认为nullif() 将有助于捕获这些未定义的实例并将它们替换为Null,以修复类型。我可以在 SQL 之前清理数据,但更喜欢直接在查询中使用nullif()。欢迎任何进一步的想法!
    • 所以,实际上我按照您的建议将数据转换为预期的类型,并通过将整个 nullif() 表达式转换为 int(或 decimal)解锁了查询.非常感谢您发布了那一点代码,否则我不会想到这个技巧!我最终的 VALUES 表达式是:(%s, NULLIF(%s,'None')::decimal, NULLIF(%s,'None')::decimal, %s, NULLIF(%s,'None')::int)
    猜你喜欢
    • 2019-03-29
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 2017-11-17
    • 2011-12-01
    • 1970-01-01
    相关资源
    最近更新 更多