Elixir (sqlalchemy): Beziehungen zwischen 3 Tabellen mit zusammengesetzten Primärschlüsseln
-
08-07-2019 - |
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.
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?
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))