Эликсир (SQLAlchemy):отношения между 3 таблицами с составными первичными ключами

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

Вопрос

У меня есть 3 стола:

  • Корпоративный стол с (company_id) первичный ключ
  • Таблица страниц с (company_id, url) первичный ключ и внешний ключ возвращаются в Компанию
  • Таблица Attr с (company_id, attr_key) первичный ключ и внешний ключ возвращаются Компании.

Мой вопрос заключается в том, как построить отношение ManyToOne из Attr обратно на Страницу, используя существующие столбцы в Attr, т. Е. company_id и 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))

Я прокомментировал несколько неудачных попыток.

В конце концов, Attr.company_id должен быть внешним ключом как для Страницы, так и для Компании (а также первичным ключом в Attr).

Возможно ли это?

Это было полезно?

Решение

Да, вы можете это сделать.У Elixir нет встроенного способа сделать это, но поскольку это тонкая оболочка на SQLAlchemy, вы можете убедить его сделать это.Поскольку в Elixir нет концепции отношения "многие к одному", которое повторно использует существующие столбцы, вам необходимо использовать GenericProperty со свойством отношения SQLAlchemy и добавить внешний ключ, используя параметры таблицы.Следующий код должен делать то, что вы хотите:

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))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top