SQLAlchemy使用对象属性进行动态查询

时间:2016-07-14 20:29:21

标签: python 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 Base类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个产品中出现一次或两次,因此在处理它们时将每个特殊价格存储在外部变量中并不完全有效。

1 个答案:

答案 0 :(得分:3)

要动态访问属性,您应该使用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])