SQLalchemy:如何以编程方式建立关系



我想动态地在两个表之间创建一个1:n的关系。我的数据库模型是通过sqlalchemy映射的,但由于我的应用程序的某些特殊功能,我无法使用默认声明方式。

,例如

class Foo(Base):
    id = Column(Integer, autoincrement=True, primary_key=True)
    flag = Column(Boolean)
class Bar(Base):
    id = Column(Integer, autoincrement=True, primary_key=True)
    foo_id = Column(Integer, ForeignKey('foo.id'))
    # declarative version:
    # foo = relationship(Foo)

所以我想在定义 bar之后的映射类" bar" 中添加名为" foo"的关系,而sqlalchemy做了定义映射器等的工作。

更新2017-09-05:为什么这对我来说是必要的?(我认为我可以省略这一点,因为我认为这主要从实际问题分散了注意力,但是由于有关于它的评论...)

首先,我没有一个数据库,而是数百/千。旧数据库中的数据不得以任何方式更改,但我希望单个源代码访问旧数据(即使数据结构和计算规则发生显着变化)。

当前我们使用多个模型定义。以后的定义扩展/修改了先前的定义。通常,我们动态地操纵Sqlalchemy模型。我们尽量不要在映射的类中拥有代码,因为我们认为在更改表多次更改表之后将更难确保该代码的正确性(代码必须在每个中间步骤中工作)。

在许多情况下,我们在模型X-1中最初定义的模型X中将表(映射类)在编程中扩展。将列添加到现有的Sqlalchemy ORM类是可以管理的。现在,我们正在添加一个新的参考列,一个现有表,relationship()提供了更好的Python API。

好吧,我上面的问题再次是Sqlalchemy的超级力量(以及我有限的理解)的一个很好的例子:

 Bar.__mapper__.add_property('foo', relationship('Foo'))

很可能我最初无法完成此工作,因为我的某些周围代码混合了添加关系和列。此外,声明列有一个重要的区别:

Column('foo', Integer)

对于列,第一个参数可以是列名,但您无法将其用于关系。relationship('foo', 'Foo')将其传递给.add_property()时触发异常。

最新更新