2014-01-30 91 views
2

我有一個數據模型,它是類似於以下內容:SQLAlchemy的物化關係

Location 1-----*<> Vacation <>*------1 TravelAgency 
        <> 
        |* 
        | 
        |1 
        Airline 

它在SQLAlchemy的執行以正常方式:休假

class Vacation(Base): 
    __tablename__ = 'vacation' 
    id = Column(Integer, primary_key=True) 
    location_id = Column(Integer, ForeignKey('location.id') 
    location = relationship("Location") 
    travel_agency_id = Column(Integer, ForeignKey('travel_agency.id') 
    travel_agency = relationship("TravelAgency") 
    airline_id = Column(Integer, ForeignKey('airline.id') 
    airline = relationship("Airline") 

class Location(Base): 
    __tablename__ = 'location' 
    id = Column(Integer, primary_key=True) 
    data = Column(Integer) 

class TravelAgency(Base): 
    __tablename__ = 'travel_agency' 
    id = Column(Integer, primary_key=True) 
    data = Column(Integer) 

class Airline(Base): 
    __tablename__ = 'airline' 
    id = Column(Integer, primary_key=True) 
    data = Column(Integer) 

分析數百個數據庫由於需要多個連接,數百萬個對象的速度太慢。在耗盡我的選項以加快使用數據庫配置選項的連接操作之後,我現在試圖使用數據庫觸發器來維護與其聚合連接的假期的物化視圖。

SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name = 'vacation_materialized'; 

column_name 
-------------- 
id 
location_id 
location$data 
travel_agency_id 
travel_agency$data 
airline_id 
airline$data 

現在我正在權衡如何從這個視圖重建度假,travel_agency和航空公司對象的選項。一種選擇是使用sqlalchemy核心查詢vacation_materialized表,然後解析行並「手動」構建對象。有沒有我應該研究的ORM功能可能會導致更「優雅」的解決方案?

回答

1

你應該能夠做到對映射物化視圖類,然後提供只讀關係屬性:

materialized_vacations = Table('materialized_vacations', metadata, autoload=True) 
locations = Table('locations', metadata, autoload=True) 

mvac_2_location = materialized_vacations.c.location_id==locations.c.location_id 

class Location(Base): 
    __table__ = locations 

class MaterializedVacation(Base): 
    __table__ = materialized_vacations 
    location = relationship("Location", primaryjoin=mvac_2_location, viewonly=True) 
    ... 

我假設在這裏,你希望把任何外國鍵入您的物化視圖。相反,我使用primaryjoin關鍵字參數指定relationship(),明確指定了連接條件。

這裏mvac_2_location創建一個sqlalchemy.sql.expression.BinaryExpression;我喜歡在使用之前單獨聲明它們,因爲它們傾向於佔用自己的大部分行,並且如果聲明瞭它們的使用位置,則參數序列將不可讀。它也使得它們可重用並可導入子模塊,這可以很方便。

構建mvac_2_location,我需要實際的表對象,我整理MaterializedVacation類的聲明之前需要他們,所以我宣佈他們老式的預聲明的方式,然後結合類使用的表說明性的論點__table__代替更常見的__tablename__。有可能有更好的方法來做到這一點,但我不確定。

+0

感謝您的反饋,但我不認爲這得到我的目的。我把我的連接「緩存」在輔助表中。我希望能夠查詢到該次表的備用映射,通過最小化連接來提高性能。您的解決方案似乎仍需要連接主表。我相信解決方案涉及CompositeProperty而不是RelationshipProperty。我在這個解決方案的嘗試被描述[在這個問題](http://stackoverflow.com/questions/22342525/sqlalchemy-compositeproperty-for-a-mapped-type)。這是一個明智的想要做的事嗎? – natb1