sqlalchemy具有动态映射和复杂对象查询功能

时间:2012-01-10 22:39:37

标签: python sqlalchemy

我有以下情况:

class MyBaseClass(object):

    def __init__(self, name):
        self.name = name
        self.period = None
        self.foo = None

    def __getitem__(self, item): 
        return getattr(self, item)

    def __setitem__(self, item, value):
        return setattr(self, item, value)

如果在运行时我需要添加一些额外的列,我们可以这样做:

my_base_class_table = Table("MyBaseClass", metadata,
           Column('name', String, primary_key=True),
           Column('period', DateTime),
           Column('foo', Float),
           )


my_base_class_table = Table("MyBaseClass", metadata, extend_existing=True)

column_list = ["value_one", "other_name", "random_XARS123"]

for col in column_list:
    my_base_class_table.append_column(Column(col, Float))

create_all()

mapper(MyBaseClass, my_base_class_table)

在此之前,我们有一个功能强大的动态表映射和扩展列。

现在,使用sqlalchemy的ORM,您可以轻松地实例化MyBaseClass并对其进行修改以反映数据库中的更改:

base_class = MyBaseClass(name="Something")
base_class.period = "2002-10-01"

使用具有未知列名称的动态列:

for col in column_list:
    base_class[col] = 10

session.add(base_class)

但实际上只有当您知道列名时才

t_query = session.query(func.strftime('%Y-%m-%d', MyBaseClass.period),
                        func.sum(MyBaseClass.foo), \
                        func.sum(MyBaseClass.other_name*MyBaseClass.value_one))

可以在不知道列名的情况下重复上一个查询(t_query)吗?我已经尝试过不同的情况但没有运气:

 func.sum(MyBaseClass[column_list[0]]*MyBaseClass.[column_list[1]])

实际上唯一可行的是执行扩展文本sql,如:

 text_query = text("SELECT strftime('%Y-%m-%d', period) as period, sum(foo) as foo, sum({0}*{1}) as bar FROM {2} ".format(column_list[0], column_list[1], "MyBaseClass")

1 个答案:

答案 0 :(得分:1)

简单getattr可以解决问题:

t_query = session.query(func.strftime('%Y-%m-%d', getattr(MyBaseClass, "period")),
                        func.sum(getattr(MyBaseClass, "foo")),
                        func.sum(getattr(MyBaseClass, "other_name") * getattr(MyBaseClass, "value_one"))
                        )