2016-07-14 3 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) 

У меня есть класс Product SQLAlchemy Base, который описывает несколько атрибутов, плюс дополнительные специальные цены, которые отличаются от прейскурантной цены.

У меня затем есть класс 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 

я позже начать итерации над каждым Product и PriceList экземпляра.

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

На данный момент мой product объект имеет новую специальную цену или несколько новых специальных цен, которые я планирую обновление в базе данных. I мог бы просто добавить мой объект в сеанс базы данных и совершить, но мне нужно получить старую цену (ы) и привязать их к своим прейскурантам до того, как я их совершу. Старые цены используются в отчете, который позже отправляется мне по электронной почте. То, что я делаю сейчас ниже

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. Перед загрузкой вы можете получить доступ к загруженному значению атрибута. 2. Даже если вы не смогли, вы всегда можете сохранить атрибут самостоятельно. – 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», хорошо знать! –