【问题标题】:SQLAlchemy dynamic query using object attribute使用对象属性的 SQLAlchemy 动态查询
【发布时间】:2016-07-15 06:10:09
【问题描述】:

我正在寻找动态查询对象的属性。在这种情况下,我不知道我将在执行时使用哪个属性或列。

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 种产品只发生一次或两次,因此在处理每个特价时将它们存储在外部变量中并不是很有效。

【问题讨论】:

  • 如果您有产品对象,为什么要重新获取价格?
  • 此时产品对象的价格已发生变化。它有一个与数据库不同的新价格。
  • 1.您可以在刷新之前访问属性的加载值。 2.即使不能,也可以自己保存属性。

标签: python sqlalchemy


【解决方案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])

【讨论】:

  • 感谢您的回答!我的问题很独特且令人困惑,但您给了我足够的支持。 getattr() 是适用于这种情况的正确工具。查询时我很困惑,因为getattr() 返回该属性的 value。在运行s.query(Object.attribute) 时,我一直认为参数不是一个值,而是一个基于类的指针……感谢您改掉这个坏习惯。我也从来不知道Session.expire,很高兴知道!
猜你喜欢
  • 2019-03-29
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多