Sélectionnez les valeurs NULL dans SQLAlchemy

Voici ma table (PostgreSQL) --

test=> create table people (name varchar primary key,
                            marriage_status varchar) ; 

test=> insert into people values ('Ken', 'married');
test=> insert into people values ('May', 'single');
test=> insert into people values ('Joe', NULL);

Je veux sélectionner toutes les personnes qui sont Pas connues pour être mariées, c'est-à-dire, y compris celles avec NULL marriage_status.

Cela ne fonctionne pas --

test=> select * from people where marriage_status != 'married' ; 
 name | marriage_status 
------+-----------------
 May  | single
(1 row)

Bien sûr, cela fait --

test=> select * from people where marriage_status != 'married'
       or marriage_status is NULL ; 
 name | marriage_status 
------+-----------------
 May  | single
 Joe  | 

Le problème est que j'y accède depuis SQLAlchemy avec --

...filter(or_(people.marriage_status!='married',
              people.marriage_status is None))

Qui est traduit en --

SELECT people.name as name,
       people.marriage_status as marriage_status
FROM people 
WHERE people.marriage_status != %(status_1)s OR False
sqlalchemy.engine.base.Engine.... {'status_1': 'married'}

Et ne fonctionne pas --

test=> select * from people where marriage_status != 'married'
       or False; 
 name | marriage_status 
------+-----------------
 May  | single
(1 row)

Pas plus --

test=> select * from people where marriage_status != 'married'
       or NULL; 
 name | marriage_status 
------+-----------------
 May  | single
(1 row)

Comment sélectionner des valeurs NULL via SQLAlchemy?

31
demandé sur saladi 2011-04-09 08:40:41

3 réponses

(comme indiqué par @augurar): parce que sqlalchemy utilise des méthodes magiques (surcharge de l'opérateur) pour créer des constructions SQL, il ne peut gérer que des opérateurs tels que != ou ==, mais ne peut pas fonctionner avec is (qui est une construction Python très valide).

Par conséquent, pour le faire fonctionner avec sqlalchemy, au lieu de:

...filter(or_(people.marriage_status!='married', people.marriage_status is None))

Vous devriez utiliser:

...filter(or_(people.marriage_status!='married', people.marriage_status == None))

, remplacez essentiellement le is None par == None. Dans ce cas, votre requête sera traduit correctement au SQL suivant:

SELECT people.name AS people_name, people.marriage_status AS people_marriage_status 
FROM people 
WHERE people.marriage_status IS NULL OR people.marriage_status != ?

Voir IS NULL dans la documentation .

69
répondu van 2017-06-02 21:20:00

Depuis SQLAlchemy 0.7.9, vous pouvez utiliser la méthode is_ de la colonne.

Une expression de filtre comme:

filter(or_(people.marriage_status!='married', people.marriage_status.is_(None)))

Va générer le SQL paramétré:

WHERE people.marriage_status != %(status_1)s OR people.marriage_status IS NULL

18
répondu jsnow 2017-06-21 14:45:07

J'ai rencontré un problème similaire

Https://groups.google.com/forum/?fromgroups#!topic/sqlalchemy/EVpxsNp5Ifg%5B1-25%5D

Réponse courte: - il n'y a pas d'opérateur de colonne pour IS (NOT) NULL maintenant, mais il y aura

En attendant, vous pouvez utiliser:

Filtre(tablename.is_deleted.op("n'EST PAS")(True))

Filtre(coalescer(tablename.is_deleted, False) != Vrai)

0
répondu Jonathan Vanasco 2012-08-18 00:33:46