2011-04-14 18 views
5

quiero hacer el equivalente deSelección nulo en SQLAlchemy

SELECT * FROM 
(SELECT foo, bar FROM baz JOIN quux ON baz.id = quux.id 
    UNION 
SELECT foo, NULL AS bar FROM baz) 
GROUP BY (foo, bar) HAVING foo = 'John Doe'; 

usando sqlalchemy 0.6, pero me parece que no puede colarse en que NULL allí.

Esto más o menos lo que tengo hasta ahora:

q1 = session.query(Baz.foo, Quux.bar).join(Quux) 
q2 = session.query(Baz.foo, None) 
#       ^^^^ This breaks! 
+0

Parece que estás intentando hacer el equivalente de una unión externa. Tal vez hay una manera de hacerlo en MySQL. – Omnifarious

+0

Es muy similar a una combinación externa. el problema es que no quiero filas de quux con bar = NULL; quux no tiene tales filas. Quiero agregar filas adicionales en la unión con esa columna nula. – SingleNegationElimination

+0

Además, no puse un punto demasiado fino, ya que mi pregunta es realmente sobre sqlalchemy, pero la base de datos que estoy consultando es en realidad Firebird. La consulta SQL suministrada devuelve los resultados deseados, simplemente no he descubierto cómo expresar eso en sqlalchemy. – SingleNegationElimination

Respuesta

0

Otra opción es utilizar sqlalchemy.text() con una instrucción select, como:

import sqlalchemy as sa 
from sqlalchemy.orm import sessionmaker 
from sqlalchemy.ext.declarative import declarative_base 

mymetadata = sa.MetaData() 
Base = declarative_base(metadata=mymetadata) 
Session = sessionmaker(bind=sa.engine) 

session = Session() 

class Person(Base): 
    __tablename__ = 'some_table' 
    id = sa.Column(sa.Integer, primary_key=True) 
    name = sa.Column(sa.String(50)) 


print sa.select([Person.name, sa.text('NULL as null_bar')]) 

>>> SELECT some_table.name, NULL as null_bar 
FROM some_table 
1

logré trabajar hacia fuera. La solución es el siguiente:

q1 = session.query(Baz.foo, Quux.bar) \ 
      .join(Quux.bar) 

q2 = session.query(Baz.foo, 
        sqlalchemy.sql.expression.literal_column('NULL as null_bar')) 

qall = q1.union(q2) 
foocol = qall.column_descriptions[0]['expr'] 
qgrp = qall.group_by([col['name'] for col in qall.column_descriptions]) 
q = qgrp.having(foocol == 'John Doe') 
q.all() 
6

Una solución aún más simple es utilizar sqlalchemy.null():

q1 = session.query(Baz.foo, Quux.bar) \ 
      .join(Quux.bar) 

q2 = session.query(Baz.foo, 
        sqlalchemy.null().label('null_bar')) 

qall = q1.union(q2) 
foocol = qall.column_descriptions[0]['expr'] 
qgrp = qall.group_by([col['name'] for col in qall.column_descriptions]) 
q = qgrp.having(foocol == 'John Doe') 
q.all()