SQLAlchemy, как создать связь или сопоставление строки типа таблицы с моделью таблицы или миксином - PullRequest
1 голос
/ 15 марта 2019

Мне нужно установить entity_type_id в качестве значения столбца, когда я сохраняю строку в общей таблице различных entity_types. Я должен иметь возможность загружать entity_type_id для каждого конкретного экземпляра во время создания экземпляра, потому что он доступен с помощью простого оператора select. Я хотел бы, чтобы этот идентификатор автоматически извлекался / устанавливался на уровне класса (или экземпляра) без выполнения запроса и / или установки вручную каждого раза, когда я сохраняю строку «entity_type».

Я попробовал entity_type_id @property в mixin, который возвращает идентификатор entity_type, используя object_session, но по причинам, которые я не до конца понимаю, orm по-прежнему вставляет null в качестве значения entity_type_id, когда я фиксирую / сбрасываю сеанс. (моё предположение, что само «свойство» - это не то же самое, что установка значения атрибута в экземпляре и / или возникновение проблемы, потому что имя столбца из базового класса имеет то же имя)

Вот уменьшенная версия соответствующих моделей в моей схеме:

class EntityType(Base):
__tablename__ = 'entity_type'

id = Column(UUID(as_uuid=True), primary_key=True, server_default=FetchedValue())
table_name = Column(String, nullable=False)
ui_label = Column(Text, unique=True, nullable=False)
entry_key = Column(Text, unique=True, nullable=False)

Модель базового класса:

class TrackedEntity(Base):

@declared_attr
def __tablename__(cls):
    return convert(cls.__name__)

__table_args__ = (
    UniqueConstraint('entity_type_id', 'label'),
)

id = Column(UUID(as_uuid=True), primary_key=True, server_default=FetchedValue())
entity_type_id = Column('entity_type_id', ForeignKey('entity_type.id'))
label = Column('label', String, nullable=False)

entity_type = relationship('EntityType')

polymorphic_discriminator = column_property(select([EntityType.table_name]).where(EntityType.id == entity_type_id).as_scalar())

@declared_attr
def entity_type_label(cls):
    return association_proxy('entity_type', 'label')

@declared_attr
def __mapper_args__(cls):
    if cls.__name__ == 'TrackedEntity':
        return {
            "polymorphic_on": cls.polymorphic_discriminator,
            "polymorphic_identity": cls.__tablename__
        }
    else:
        return {"polymorphic_identity": cls.__tablename__}

Детский класс mixin:

class TrackedEntityMixin(object):
        # noinspection PyMethodParameters

    @declared_attr
    def id(cls) -> Column:
        return Column(ForeignKey('tracked_entity.id'), primary_key=True)
    #gets me the id but isn't very helpful like this, still needs to be manually set like child.entity_type_id = child._entity_type_id
    @property
    def _entity_type_id(self):
        return object_session(self). \
            scalar(
            select([EntityType.id]).
                where(EntityType.table_name == self.__tablename__)
        )

Модель детского класса:

class DesignedMolecule(TrackedEntityMixin, TrackedEntity):


      extra = Column('extra', String)
      parents = relationship('TrackedEntity', secondary='mix_dm_parent_entity')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...