Elixir(SqlAlchemy):具有复合主键的3个表之间的关系

时间:2009-05-07 16:50:58

标签: python sqlalchemy python-elixir

我有3张桌子:

  • 包含(company_id)主键的公司表
  • 包含(company_id, url)主键和&的页面表回到公司的外键
  • 包含(company_id, attr_key)主键和&的Attr表。回到公司的外键。

我的问题是如何使用Attr中的现有列(即company_idurl)构建从Attr返回到Page的ManyToOne关系?

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需要是Page和Company的外键(以及Attr中的主键)。

这可能吗?

1 个答案:

答案 0 :(得分:2)

是的,你可以这样做。 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))