Создание динамического класса в SQLalchemy
-
03-10-2019 - |
Вопрос
Нам необходимо создать классы SQLALCHEMY для доступа к нескольким внешним источникам данных, которые со временем будут увеличиваться. Мы используем декларативную базу для наших основных моделей ORM, и я знаю, что мы можем вручную указать новые классы ORM, используя автозагрузку = True для автоматического создания сопоставления.
Проблема в том, что мы должны иметь возможность создавать их динамически принимать что-то подобное:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
stored={}
stored['tablename']='my_internal_table_name'
stored['objectname']='MyObject'
и превращать его во что-то подобное динамично:
class MyObject(Base):
__tablename__ = 'my_internal_table_name'
__table_args__ = {'autoload':True}
Мы не хотим, что классы сохраняются дольше, чем необходимо, чтобы открыть соединение, выполнять запросы, а затем закрывать соединение. Поэтому в идеале мы можем поставить элементы в «сохраненную» переменную выше в базу данных и потянуть их по мере необходимости. Другая задача состоит в том, что имя объекта (например, «MyObject») может использоваться на разных соединениях, поэтому мы не можем определить его один раз и сохранить его.
Любые предложения о том, как это может быть достигнуто, будет высоко оценена.
Спасибо...
Решение
Вы можете динамически создавать MyObject
с использованием 3-аргумент вызов type
:
type(name, bases, dict)
Return a new type object. This is essentially a dynamic form of the
class statement...
Например:
mydict={'__tablename__':stored['tablename'],
'__table_args__':{'autoload':True},}
MyObj=type(stored['objectname'],(Base,),mydict)
print(MyObj)
# <class '__main__.MyObject'>
print(MyObj.__base__)
# <class '__main__.Base'>
print(MyObj.__tablename__)
# my_internal_table_name
print(MyObj.__table_args__)
# {'autoload': True}