2016-07-14 64 views
0

我正在尋找動態查詢對象的屬性。我不知道在執行時將使用哪種屬性或列。使用對象屬性的SQLAlchemy動態查詢

class Product(Base): 
    __tablename__ = 'products' 

    sku = Column(String, primary_key=True) 
    list_price = Column(String) 
    status = Column(String) 
    url = Column(String) 
    special_price1 = Column(String) 
    special_price2 = Column(String) 
    special_price3 = Column(String) 

我有一個SQLAlchemy的基類Product描述從標價不同的幾個屬性,再加上額外的特殊價格。

然後我有一個PriceList類,它有權訪問額外的資源和方法來幫助報告和更新'products'表中的列。此類存儲有關所有Product對象的唯一特殊價目表的信息。

class PriceList: 

    def __init__(self, name, db_col_name): 
     # Display name 
     self.name = name 

     # Used for querying the database for a specific column 
     # This will always be one of the 4 price related column names 
     # list_price, special_price1, special_price2, or special_price3 
     self.db_col_name = db_col_name 

後來我開始在每個ProductPriceList實例迭代。

for product in products: 
    for price_list in price_lists: 
     # Do stuff 

在這一點上我product對象有一個新的特殊價格,或多個新的特殊的價格,我打算在更新數據庫。我可能只需將我的對象添加到數據庫會話並提交,但我需要獲取舊價格並在提交之前將它們與它們各自的價目表鏈接。過去的價格被用於後來通過電子郵件發送給我的報告中。我現在正在做的是低於

for product in products: 
    sku = product.sku 
    for price_list in price_lists: 
     # New price 
     new_price = product.__getattribute__(price_list.db_col_name) 

     # Get the existing special price from the database 
     old_price = s.query(Product.__getattribute__(Product, price_list.db_col_name)).filter(Product.sku.like(sku)).first() 

我覺得我比大幅使用__getattribute __複雜此()。它的工作原理,但這似乎並不pythonic。有沒有人知道更新之前獲取未知列的價值的更好方法?數據庫更新每500個產品只發生一次或兩次,因此在處理期間將每個特殊價格存儲在外部變量中時效率不高。

+0

如果您有產品對象,您爲什麼要重新提價? – univerio

+0

該點產品對象的價格已更改。它具有與數據庫不同的新價格。 –

+0

1.在刷新之前,您可以訪問屬性的加載值。即使你不能,你也可以自己保存屬性。 – univerio

回答

1

要動態訪問屬性,應該使用內建的getattr

new_price = getattr(product, price_list.db_col_name) 

如果實例是陳舊的,你應該使用Session.expire,這意味着在接下來的一次訪問,他們會從數據庫中檢索的屬性。

s.expire(product) 

# or only expire price 
s.expire(product, [price_list.db_col_name]) 
+0

感謝您的回答!我的問題是獨特而令人困惑的,但你給了我足夠的支持。 'getattr()'是在這種情況下使用的正確工具。在查詢時我很困惑,因爲'getattr()'返回該屬性的**值**。在運行's.query(Object.attribute)時'我一直認爲這個參數不是一個值,而是更多的基於類的指針......感謝你打破這個壞習慣。我也從來不知道'Session.expire',很高興知道! –