2017-03-01 8 views
0

NULLIF 함수를 사용하여 psycopg2를 통해 INSERT INTO 명령의 일부 빈 항목을 필터링하려고합니다.Psycopg2 형식 오류가있는 NULLIF 사용

NULLIF 함수가 텍스트로 해석되는 것처럼 열이 숫자를 필요로하는 경우 문제가되지 않습니다.

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

I 사용 문자열 배열의 일부 데이터를 삽입 :

내 표 5 열의 포함 이때

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 올바르게 처리 및 제 4 스트링 % 삽입 s from myArray 또는 Null (배열에 '없음'이 포함되어 있는지 여부에 따라 다름). 내가 정수 5 열,에 NULLIF를 적용하려고하면

그러나, 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 값을 전달하면 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

감사합니다. 그러나 "실제"'없음 '을 전달할 수 없다는 사실은 사실 nullif()가 필요한 이유입니다. 내 배열은 데이터가 "문자열로 된"Ajax 게시 명령에서 가져온 것입니다. 이 문제는 분명히 숫자로 SQL에서 올바르게 읽혀지는 정수에서는 문제가되지 않지만 때로는 정수 중에서 SQL 명령을 차단하는 정의되지 않은 값입니다. 난'nullif()'이 미정의 인스턴스를 잡는 데 도움이 될 것이라고 생각하고 그들을 Null로 대체, 유형을 수정합니다. 나는 SQL 이전에 데이터를 정리할 수 있지만 쿼리에서 직접'nullif()'를 선호합니다. 더 이상의 생각은 환영합니다! – sc28

+0

사실, 당신이 제안한대로 데이터를 원하는 형식으로 캐스팅하는 방법을 조금 보았습니다. 전체'nullif()'표현식을'int' (또는'decimal')로 변환하면 쿼리가 잠금 해제되었습니다. 그 작은 코드를 게시 해 주셔서 고마워요. 그렇지 않으면이 트릭을 생각하지 않았을 것입니다! 최종 VALUES 표현식은 다음과 같습니다.'% s, NULLIF (% s, '없음') :: 십진수, NULLIF (% s, '없음') :: 십진수, % s, NULLIF (% s, '없음') : : int)' – sc28