Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find null values with SELECT query in psycopg?

I am using psycopg2 library in python and the INSERT query works good when I insert null Value with None, but when I want to do SELECT null values, with None doesn't return any.

cur.execute("SELECT id FROM registro WHERE id_movil = (%s);", (None,))

This query doesnt return any rows, i dont know where is the error.

Anyone know how to make SELECT query's to find null values in a DB?

like image 221
Telmo Aldalur Avatar asked Sep 09 '15 07:09

Telmo Aldalur


People also ask

How do I SELECT NULL values in PostgreSQL?

Example - With INSERT Statement INSERT INTO contacts (first_name, last_name) SELECT first_name, last_name FROM employees WHERE employee_number IS NULL; This PostgreSQL IS NULL example will insert records into the contacts table where the employee_number contains a NULL value.

How do I use NULL in PostgreSQL?

The PostgreSQL NULL is the term used to represent a missing value. A NULL value in a table is a value in a field that appears to be blank. A field with a NULL value is a field with no value. It is very important to understand that a NULL value is different from a zero value or a field that contains spaces.

IS NULL operator in PostgreSQL?

PostgreSQL IS NOT NULL operator.

What does Psycopg do?

Psycopg converts Python variables to SQL values using their types: the Python type determines the function used to convert the object into a string representation suitable for PostgreSQL. Many standard Python types are already adapted to the correct SQL representation.


3 Answers

First thing to do is find out what query it's turning your command into:

print(cur.mogrify("SELECT id FROM registro WHERE id_movil = (%s);", (None,)))

If that gives you anything other than an IS NULL codition check, it won't get NULLs from the table.

Specifically, if you see the phrase = NULL, you'll know it's not being translated correctly(1) and you'll have to do something like:

if var is None:
    cur.execute("SELECT id FROM registro WHERE id_movil IS NULL;")
else:
    cur.execute("SELECT id FROM registro WHERE id_movil = (%s);", (var,))

Or, if you know you're always looking for NULL values (as your use of the constant None seems to indicate), just use:

cur.execute("SELECT id FROM registro WHERE id_movil IS NULL;")

(1) It's quite possible that only the %s is replaced with a NULL when the argument is None, and it's not quite clever enough to go back and change = into IS (or <> into IS NOT).

This would explain why this works:

cur.execute("INSERT into mytbl value (%s);", (None,))

(because substitution of only the %s gives the command you want), but anything with = NULL will not act as expected, unless you've been burnt by it enough times to know what to expect :-).

like image 84
paxdiablo Avatar answered Oct 02 '22 19:10

paxdiablo


Try this

cur.execute("SELECT id FROM registro WHERE (id_movil = (%s) or id_movil is null);", (movil,))
like image 25
Rad Avatar answered Oct 02 '22 18:10

Rad


An alternative which I'm currently experimenting with is a postgres setting called transform_null_equals (https://www.postgresql.org/docs/13/runtime-config-compatible.html#GUC-TRANSFORM-NULL-EQUALS)

you can set it in postgresql.conf or however you do your config (i'm using docker-compose for local dev and RDS for prod, so that means a parameter group).

transform_null_equals = 1

The effect is that postgres then just magically transforms any = NULL queries into IS NULL without you having to think about it! 🎉

like image 43
hwjp Avatar answered Oct 02 '22 20:10

hwjp