Sqlalchemy existe con herencia unida y Firebird

Intenté usar la herencia de tablas unidas de sqlaclhemy y tuve un suceso extraño.

class CommonObject(Base):
    __tablename__ = "objects"
    id = Column("objid", Integer, primary_key=True)
    objname = Column(String(32))
    ...    

class GoodsPlacement(Container, Loadable, Dumpable):
    __tablename__ = "goods_placements"
    id = Column("objid", Integer, ForeignKey("containers.objid"), primary_key=True)
    ...

class Departure(CommonObject):
     __tablename__ = "departures"
    id = Column(Integer, ForeignKey("objects.objid"),  primary_key=True)
    content_id = Column(Integer, ForeignKey("goods_placements.objid"))
    content = relationship("GoodsPlacement",
        primaryjoin="Departure.content_id==GoodsPlacement.id",
        foreign_keys=[content_id],
        lazy='joined',
        backref="departures")
    ...

Cuando escribo consulta:

session.query(GoodsPlacement).filter(~GoodsPlacement.departures.any(Departure.status_id < 2))

me genera algo como esto:

SELECT 
    objects.objid AS objects_objid,
    goods_placements.objid AS goods_placements_objid,
    objects.objname AS objects_objname 
FROM objects
JOIN goods_placements ON objects.objid = goods_placements.objid 
WHERE NOT (EXISTS (
    SELECT 1 
    FROM (
        SELECT
            objects.objid AS objects_objid,
            objects.objname AS objects_objname,
            departures.id AS departures_id,
            departures.content_id AS departures_content_id,
            departures.status_id AS departures_status_id 
        FROM objects
        JOIN departures ON objects.objid = departures.id)
    AS anon_1, objects 
    WHERE anon_1.departures_content_id = objects.objid
        AND anon_1.departures_status_id < :status_id_1)
)

Y esto no funciona porque los objetos en la cláusula exist anulan los objetos externos. Como la solución que utilicé existe directamente desde sqlexpression,

session.query(GoodsPlacement).filter(~exists([1],
    and_("departures.status_id<2",
         "departures.content_id=goods_placements.objid"),
    from_obj="departures"))

pero depende en gran medida de los nombres de columnas y tablas.

¿Cómo puedo especificar el alias para la tabla de objetos en la declaración existe?

Debian sibilante, python-2.7.3rc2, sqlaclhemy 0.7.7-1

preguntado el 22 de mayo de 12 a las 11:05

¿Puede agregar también el resto de los query definición, y no sólo filter parte. -

session.query(Colocación de Bienes).filter(...).all() -

estas asignaciones no están completas. ¿Es GoodsPlacement una subclase de CommonObject? ¿Puede formular un ejemplo de reproducción completo (sin incluir cosas que no son relevantes para la consulta mal producida) y enviar por correo electrónico la lista de SQLAlchemy, por favor? Las relaciones genéricas entre mapeadores heredados de tablas unidas son extremadamente complicadas. -

se agregaron boletos sqlalchemy.org/trac/ticket/2491 y sqlalchemy.org/trac/ticket/2492. Es probable que el error no se solucione hasta la versión 0.8, donde se mejoró la mecánica de any(). -

1 Respuestas

hay un error relacionado con el sistema declarativo en la forma en que configura las columnas. El nombre "objid" que está dando a las columnas, distinto del nombre del atributo "id", es la fuente del problema aquí. El siguiente caso de prueba se aproxima a su sistema anterior y muestra una solución alternativa hasta que se solucione el error:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base= declarative_base()

class CommonObject(Base):
    __tablename__ = "objects"
    id = Column("objid", Integer, primary_key=True)
    objname = Column(String(32))

class Container(CommonObject):
    __tablename__ = 'containers'
    id = Column("objid", Integer, ForeignKey("objects.objid"),  primary_key=True)

class GoodsPlacement(Container):
    __tablename__ = "goods_placements"
    id = Column("objid", Integer, ForeignKey("containers.objid"), primary_key=True)


class Departure(CommonObject):
    __tablename__ = "departures"
    id = Column(Integer, ForeignKey("objects.objid"),  primary_key=True)
    content_id = Column(Integer, ForeignKey("goods_placements.objid"))
    status_id = Column(Integer)
    content = relationship("GoodsPlacement",
        primaryjoin=lambda:Departure.__table__.c.content_id==GoodsPlacement.__table__.c.objid,
        backref="departures"
        )

session = Session()
print session.query(GoodsPlacement).filter(~GoodsPlacement.departures.any(Departure.status_id < 2))

salida:

SELECT objects.objid AS objects_objid, containers.objid AS containers_objid, goods_placements.objid AS goods_placements_objid, objects.objname AS objects_objname 
FROM objects JOIN containers ON objects.objid = containers.objid JOIN goods_placements ON containers.objid = goods_placements.objid 
WHERE NOT (EXISTS (SELECT 1 
FROM (SELECT objects.objid AS objects_objid, objects.objname AS objects_objname, departures.id AS departures_id, departures.content_id AS departures_content_id, departures.status_id AS departures_status_id 
FROM objects JOIN departures ON objects.objid = departures.id) AS anon_1 
WHERE anon_1.departures_content_id = goods_placements.objid AND anon_1.departures_status_id < :status_id_1))

respondido 01 nov., 13:18

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.