Elixir (sqlalchemy): Beziehungen zwischen 3 Tabellen mit zusammengesetzten Primärschlüsseln

StackOverflow https://stackoverflow.com/questions/835834

Frage

Ich habe 3 Tabellen:

  • Ein Unternehmen Tabelle mit (company_id) Primärschlüssel
  • Eine Seite Tabelle mit (company_id, url) Primärschlüssel und Fremdschlüssel zurück zum Unternehmen
  • Ein Attr Tabelle mit (company_id, attr_key) Primärschlüssel und Fremdschlüssel zurück an das Unternehmen.
mit den vorhandenen Spalten in Attr, das heißt company_id und url

Meine Frage ist, wie die ManyToOne Beziehung von Attr zurück zur Seite konstruieren?

from elixir import Entity, has_field, setup_all, ManyToOne, OneToMany, Field, Unicode, using_options
from sqlalchemy.orm import relation

class Company(Entity):
    using_options(tablename='company')
    company_id = Field(Unicode(32), primary_key=True)
    has_field('display_name', Unicode(255))
    pages = OneToMany('Page')

class Page(Entity):
    using_options(tablename='page')
    company = ManyToOne('Company', colname='company_id', primary_key=True)
    url = Field(Unicode(255), primary_key=True)

class Attr(Entity):
    using_options(tablename='attr')
    company = ManyToOne('Company', colname='company_id', primary_key=True)
    attr_key = Field(Unicode(255), primary_key=True)
    url = Field(Unicode(255)) #, ForeignKey('page.url'))
    # page = ManyToOne('Page', colname=["company_id", "url"])
    # page = relation(Page, backref='attrs', foreign_keys=["company_id", "url"], primaryjoin=and_(url==Page.url_part, company_id==Page.company_id))

Ich habe auf Kommentar einige Fehlversuche.

Am Ende Attr.company_id muß eine foreignkey sowohl Seite und Unternehmen (auch als Primärschlüssel in Attr) sein.

Ist das möglich?

War es hilfreich?

Lösung

Ja, Sie können dies tun. Elixir hat kein in Art und Weise gebaut, dies zu tun, sondern weil es sich um eine dünne Hülle ist auf SQLAlchemy können Sie davon überzeugen, dies zu tun. Da Elixir hat kein Konzept einer Viele-zu-Eins-Beziehung, die vorhandenen Spalten wieder verwendet, müssen Sie die GenericProperty mit der SQLAlchemy Beziehung Eigenschaft verwenden und den Fremdschlüssel mit Tabellenoptionen hinzuzufügen. Der folgende Code sollte tun, was Sie wollen:

from elixir import Entity, has_field, setup_all, ManyToOne, OneToMany, Field, Unicode, using_options, using_table_options, GenericProperty
from sqlalchemy.orm import relation
from sqlalchemy import ForeignKeyConstraint

class Company(Entity):
    using_options(tablename='company')

    company_id = Field(Unicode(32), primary_key=True)
    display_name = Field(Unicode(255))
    pages = OneToMany('Page')

class Page(Entity):
    using_options(tablename='page')

    company = ManyToOne('Company', colname='company_id', primary_key=True)
    url = Field(Unicode(255), primary_key=True)
    attrs = OneToMany('Attr')

class Attr(Entity):
    using_options(tablename='attr')

    page = ManyToOne('Page', colname=['company_id', 'url'], primary_key=True)
    attr_key = Field(Unicode(255), primary_key=True)

    using_table_options(ForeignKeyConstraint(['company_id'], ['company.company_id']))
    company = GenericProperty(relation(Company))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top