Question

J'ai 3 tables:

  • Une table de société avec (id_entreprise) clé primaire
  • Une table de pages avec (id_entreprise, url) clé primaire & amp; une clé étrangère vers la société
  • Une table Attr avec (company_id, attr_key) clé primaire & amp; une clé étrangère à la société.

Ma question est de savoir comment construire la relation ManyToOne de Attr vers Page en utilisant les colonnes existantes dans Attr, c'est-à-dire company_id et 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))

J'ai commenté certaines tentatives infructueuses.

Au final, Attr.company_id devra être une clé étrangère pour la page et la société (ainsi qu'une clé primaire dans Attr).

Est-ce possible?

Était-ce utile?

La solution

Oui, vous pouvez le faire. Elixir n’a pas de méthode intégrée pour le faire, mais comme il s’agit d’un wrapper fin sur SQLAlchemy, vous pouvez le convaincre de le faire. Elixir n'ayant pas le concept d'une relation plusieurs-à-un qui réutilise des colonnes existantes, vous devez utiliser GenericProperty avec la propriété de relation SQLAlchemy et ajouter la clé étrangère à l'aide des options de table. Le code suivant doit faire ce que vous voulez:

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))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top