Sqlalchemy existe con herencia unida y Firebird
Frecuentes
Visto 288 veces
1
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
1 Respuestas
1
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 python sqlalchemy exists declarative class-table-inheritance or haz tu propia pregunta.
¿Puede agregar también el resto de los
query
definición, y no sólofilter
parte. - vansession.query(Colocación de Bienes).filter(...).all() - Igel
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. - zzzeek
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(). - zzzeek