我正在使用 SQLModel,它是 SQLAlchemy 的包装器。
数据模型包括:
class Line(SQLModel, table = True):
id: int | None = Field(default = None, primary_key = True)
name: str
class Product(SQLModel, table = True):
id: int | None = Field(default = None, primary_key = True)
line_id: int | None = Field(default = None, foreign_key = 'line.id')
myob_uid: str
myob_name: str
weight: float
从两个表中选择列子集的示例查询:
query = select(Product.id, Product.weight, Line.name)\
.join(Line)
注意 select 语句中表名的重复。在 SQLAlchemy 中我们可以这样做:
select(Product.c['id','weight'], Line.c['name'])
但是 c 属性在 SQLModel 中不可用。
有没有办法在不重复名称的情况下按多个列对表进行子集化?
这是一个迂腐的要求。然而,编写 DRY 查询很重要,因为它们变得庞大且复杂。
我已经尝试了以下两种方法,但它们在可读性方面并不那么优雅:
select(*[getattr(Product, x) for x in ['id','weight']], Line.name)
.不幸的是,在
SQLModel
中,没有像 SQLAlchemy Core 中那样直接的 c
属性,因为 SQLModel
遵循更具声明性的 ORM 模式。
不过,您仍然可以通过使用 Python 功能来实现 DRY 查询,以避免重复。
您可以使用列表理解,但通过将此功能包装在实用程序函数中使其更具可读性。这样,您就可以保持查询干燥,而无需在
select
语句中重复表名。
这是代码示例。
# Helper function to dynamically extract columns from a table
def get_columns(table: SQLModel, columns: List[str]):
return [getattr(table, column) for column in columns]
# Use the helper function to get columns for both tables
query = select(*get_columns(Product, product_columns), *get_columns(Line, line_columns)).join(Line)
我希望这会有所帮助。