2017-09-05 34 views
0

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

E.g.

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) 

所以我想定义酒吧后,名为“foo”的关系添加到映射的类“BAR” 和SQLAlchemy的定义做了一个映射器等。它的工作

更新2017-09 -05:为什么这对我有必要? (我认为我可以省略这个,因为我认为它主要是分散实际问题来解决,但因为有评论关于它...)

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

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

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

+0

背后的原因是什么?你想在创建多重关系时使用外部模型列表吗? – krassowski

+0

然后,只需为该课程添加关系属性,尽管@ krassowski是正确的:您为什么需要它? –

+0

@ ilja-everilä:你能详细说明一下吗?我需要将关系定义与实际声明完全分离。基本上我想知道如何操作SQLAlchemy的内部,但我找不到(非常好)文档中的正确部分,我希望有人可以节省我几个小时的时间阅读SQLAlchemy源代码... :-) –

回答

0

好了,我上面的问题又是SQLAlchemy的的超能力(和我有限的了解)一个很好的例子:

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

很有可能我无法最初得到这个工作,因为我的一些周围的代码混合添加关系和列。也有是宣告列一个重要的区别:

Column('foo', Integer) 

列的第一个参数可以是列名,但你不能用这个关系。 relationship('foo', 'Foo')传递给.add_property()时触发异常。

相关问题