Sqlalchemy динамически создает таблицу и сопоставленный класс

Учитывая набор имен столбцов и их типов, цель состоит в том, чтобы
создать экземпляр таблицы и соответствующий сопоставленный класс.

Это связано с вопросом, размещенным здесь: Создание динамического класса в SQLAlchemy.

Пока у меня есть следующее:

table = Table(tbl, 
              metadata, 
             *(Column(col, ctype, primary_key=pk, index=idx) for  col,  ctype, pk, idx in zip(attrs, types, primary_keys, indexes))
              )

Это создает объект таблицы. Теперь мне нужно создать соответствующий класс.

mydict={'__tablename__':tbl}
cls = type(cls_name, (Base,), mydict)

Это дает мне следующую ошибку:

ArgumentError: Mapper Mapper|persons_with_coord|t_persons_w_coord не удалось собрать ни одного столбца первичного ключа для сопоставленной таблицы

Мой вопрос заключается в том, как указать первичные ключи как часть создания класса. И после создания класса мне нужно вызвать mapper следующим образом:

mapper(cls, table)

person Sandeep    schedule 15.02.2017    source источник


Ответы (1)


Отображение mydict должно либо включать объект таблицы, либо указывать, что таблицу необходимо загрузить из базы данных.

Это должно работать

mydict={'__tablename__':tbl, '__table__': table}

Это также должно работать

mydict={'__tablename__':tbl, '__table_args__': ({'autoload':True},)}

первичные ключи уже указаны при создании table. При создании декларатива указывать их заново не нужно, но если это требуется (скажем, для сложного ключа), то его следует указать в __table_args__.

Mapper должен вызываться в декларативном классе. Однако у вновь созданного декларатива нет объекта метаданных. Добавление метаданных заставит динамически созданный декларативный элемент вести себя больше как обычный декларативный элемент, поэтому я бы рекомендовал поместить эту строку после создания класса.

cls.metadata = cls.__table__.metadata

Итак, полные правки могут быть:

mydict={'__tablename__':tbl, '__table__': table}
cls = type(cls_name, (Base,), mydict)
cls.metadata = cls.__table__.metadata
person Haleemur Ali    schedule 16.02.2017