SQLAlchemy принудительно применяет подмножество внешних ключей в связанных отношениях "многие ко многим" - PullRequest
0 голосов
/ 06 августа 2020

При написании инструмента упаковки у меня возникают проблемы с проверкой набора внешних ключей из одного отношения n2m по списку доступных ключей из-за другого отношения.

Условия:

  • Артефакт имеет разные версии ArtifactVersions
  • Артефакт имеет несколько FileChanges
  • FileChange имеет класс свойств
  • PropertyClass имеет несколько PropertyGroups
  • Пакет имеет несколько версий ArtifactVersions (с уникальными артефактами)

А теперь проблема:

  • Пакет должен иметь PropertyGroup для каждого FileChange каждого определенного им артефакта

Я совершенно не знаю, как это сделать sh. Валидаторы кажутся проблемными, потому что мне нужно будет запросить БД для проверки внешних ключей.

Код:

class Artifact(db.Model):
    """Represent an Artifact."""

    __tablename__ = "artifact"
    id = db.Column(db.String(50), primary_key=True)
    versions = db.relationship(
        "ArtifactVersion",
        backref="artifact",
        cascade="all, delete, delete-orphan",
        single_parent=True,
        lazy="joined",
    )
    file_changes = db.relationship(
        "FileChange",
        backref="artifact",
        cascade="all, delete-orphan",
        single_parent=True,
        lazy="dynamic",
    )


class ArtifactVersion(db.Model):
    """Represent a specific Artifact Version."""

    __tablename__ = "artifact_version"
    __table_args__ = (
        db.UniqueConstraint("version", "artifact_id", name="unique_property"),
    )
    id = db.Column(db.Integer, primary_key=True)
    version = db.Column(db.String(50))
    uri = db.Column(db.String(500), nullable=False)
    artifact_id = db.Column(db.String(50), db.ForeignKey("artifact.id"), nullable=False)


class FileChange(db.Model):
    """Represent a File of an Artifact to change."""

    __tablename__ = "file_change"
    id = db.Column(db.Integer, primary_key=True)
    path = db.Column(db.String(500))
    artifact_id = db.Column(db.String(50), db.ForeignKey("artifact.id"))
    property_class_id = db.Column(db.String(50), db.ForeignKey("property_class.id"))


class PropertyClass(db.Model):
    """Represent a PropertyClass."""

    __tablename__ = "property_class"
    id = db.Column(db.String(50), primary_key=True)
    file_changes = db.relationship("FileChange", backref="property_class")
    property_groups = db.relationship(
        "PropertyGroup",
        backref="property_class",
        cascade="all, delete, delete-orphan",
        single_parent=True,
        lazy=False,
    )

class PropertyGroup(db.Model):
    __tablename__ = "property_group"
    __table_args__ = (
        db.UniqueConstraint("name", "property_class_id", name="unique_property"),
    )
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    property_class_id = db.Column(db.String(50), db.ForeignKey("property_class.id"))


class Package(db.Model):
    """Represent a Package."""

    __tablename__ = "package"
    id = db.Column(db.String(50), primary_key=True)

    artifact_versions = association_proxy(
        "package_artifact_versions", "artifact_version", creator=_version_find
    )
    property_groups = association_proxy(
        "package_property_groups", "property_group", creator=_find_prop_group
    )


class PackagePropertyGroup(db.Model):
    """N2M Model"""

    __tablename__ = "package_property_group"
    __table_args__ = (
        db.UniqueConstraint(
            "package_id", "property_class_id", name="unique_property_group_class"
        ),
    )
    package_id = db.Column(db.String(50), db.ForeignKey("package.id"), primary_key=True)
    property_group_id = db.Column(
        db.Integer, db.ForeignKey("property_group.id"), primary_key=True
    )
    property_class_id = db.Column(
        db.String(50), db.ForeignKey("property_group.property_class_id")
    )
    package = db.relationship(
        "Package",
        backref=db.backref(
            "package_property_groups", cascade="all, delete-orphan", lazy="joined"
        ),
    )
    property_group = db.relationship(
        "PropertyGroup", foreign_keys="PackagePropertyGroup.property_group_id"
    )


class PackageArtifactVersion(db.Model):
    """N2M Model."""

    __tablename__ = "package_artifact_version"
    package_id = db.Column(db.String(50), db.ForeignKey("package.id"), primary_key=True)
    artifact_version_id = db.Column(
        db.Integer, db.ForeignKey("artifact_version.id"), primary_key=True
    )
    package = db.relationship(
        "Package",
        backref=db.backref(
            "package_artifact_versions", cascade="all, delete-orphan", lazy="joined"
        ),
    )
    artifact_version = db.relationship("ArtifactVersion")

As far as i understand a ForeignKeyConstraint would enable me to ensure that no wrong PropertyGroups are added to the PackagePropertyGroup association, but i dont see how i could *enforce* that each PackageArtifactVersion has a valid PropertyGroup added to it.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...