Domanda

Ho 3 tabelle:

  • Una tabella aziendale con (company_id) chiave primaria
  • Una tabella di pagine con (company_id, url) chiave primaria e amp; una chiave esterna di nuovo in Azienda
  • Una tabella Attr con (company_id, attr_key) chiave primaria e amp; una chiave esterna per la società.

La mia domanda è come costruire la relazione ManyToOne da Attr torna alla pagina usando le colonne esistenti in Attr, ovvero company_id e url ?

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))

Ho commentato alcuni tentativi falliti.

Alla fine, Attr.company_id dovrà essere una chiave straniera sia per Page che per la Società (nonché una chiave primaria in Attr).

È possibile?

È stato utile?

Soluzione

Sì, puoi farlo. L'elisir non ha un modo integrato per farlo, ma poiché è un wrapper sottile su SQLAlchemy puoi convincerlo a farlo. Poiché l'elisir non ha il concetto di una relazione molti-a-uno che riutilizza le colonne esistenti, è necessario utilizzare GenericProperty con la proprietà della relazione SQLAlchemy e aggiungere la chiave esterna utilizzando le opzioni della tabella. Il seguente codice dovrebbe fare quello che vuoi:

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))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top