sqlalchemy с динамическим отображением и запросом сложных объектов - PullRequest
1 голос
/ 11 января 2012

У меня следующая ситуация:

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)

До тех пор, пока у нас не будет полностью функционировать отображение динамических таблиц с расширенными столбцами.

Теперь, используя ORM в sqlalchemy, вы можете легко создать экземпляр 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 Ответ

1 голос
/ 11 января 2012

Простой 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"))
                        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...