1

나는 sqlaclhemy를 사용하여 테이블 상속을 시도했는데 이상한 상황이 발생했습니다.Sqlalchemy가 상속 및 Firebird에 합류했습니다.

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

는 다음과 같이 나에게 뭔가를 생성합니다 :

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") 
    ... 

나는 쿼리를 작성하는 경우

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) 
) 

을 그리고 존재 절에있는 객체가 외부 객체를 무시하기 때문에이 작동하지 않습니다. 내가 사용 으로 해결 방법은 직접 sqlexpression에서

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

존재하지만 강한 열 및 테이블 이름에서 달려있다.

어떻게 exist 문에서 객체 테이블의 별칭을 지정할 수 있습니까?

데비안 씩씩 거리는, 파이썬-2.7.3rc2, 그것은 열을 설정하는 방법에 선언적 시스템을 포함하는 버그가있다 0.7.7-1

+0

당신은 또한'query' 정의의 나머지 부분을 추가하고, 단지 주시겠습니까 '필터'부분. – van

+0

session.query (GoodsPlacement) .filter (...). all() – Igel

+0

이러한 매핑이 완료되지 않았습니다. GoodsPlacement는 CommonObject의 하위 클래스입니까? 완전한 재생산 예 (잘못 제작 된 질의와 관련이없는 것을 포함하지 않음)를 공식화하고 SQLAlchemy 목록을 전자 메일로 보내주십시오. 조인 된 테이블 상속 mappers 간의 일반적인 관계는 매우 복잡합니다. – zzzeek

답변

1

을 sqlaclhemy. "id"속성 이름과는 다른 열을 제공하는 "objid"이름이 여기에있는 문제의 근원입니다. 아래의 테스트 케이스는 위의 시스템에 근접하고 버그가 해결 될 때까지 해결 방법을 보여줍니다

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)) 

출력 :

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)) 
관련 문제