SQLAlchemy与没有外键的经典关系

时间:2016-10-25 16:07:28

标签: python sqlalchemy

我试图联系两张有多个' secondary'表。而不是声明性语法,我使用经典语言是必要的。这是一个简化的架构:

class Apple:
  def __init__(self, id=None, name=None):
    # ...

class Recipe:
  def __init__(self, id=None, appleId=None, name=None):
    # ...

class Blog:
  def __init__(self, id=None, name=None, recipeId=None, bloggerId=None):
    # ...

class Blogger:
  def __init__(self, name)
    # ...

appleTable = Table('Apple', metadata, Column('id', Integer, primary_key=True), Column('name', String(256)))
recipeTable = Table('Recipe', metadata, Column('id', Integer, primary_key=True), Column('name', String(256)), Column('appleId', Integer, ForeignKey('Apple.id')))
blogTable = Table('Blog', metadata, Column('id', Integer, primary_key=True), Column('name', String(256)), Column('recipeId', Integer, ForeignKey('Recipe.id')), Column('bloggerId', Integer, ForeignKey('Blogger.id')) ) 
bloggerTable = Table('Blogger', metadata, Column('id', Integer, primary_key=True), Column('name', String(256)))


# call mapper on all tables/classes
# ... #

# Relate 'Apple' to 'Blogger' using 'Recipe' and 'Blog' as intermediates 
Apple.appleBloggers = relationship(Blogger, secondary=..., primaryjoin=..., secondaryjoin=...)

我需要在appleBloggers的{​​{1}}属性中放置什么样的关系才能检索所有关于苹果食谱博客的博主?

编辑:解决方案

另一个@univerio的解决方案发布在下面。区别在于映射对象与表变量的使用。我还添加了一个Apple参数,用于阻止对属性的写入。

viewonly

原创尝试

以下是我尝试的内容:

mapper(Apple, appleTable, properties = {
  "appleBloggers": relationship(Blogger,
            secondary=join(Recipe, Blog, Recipe.id == Blog.recipeId),
            secondaryjoin=lambda: and_(Apple.id == Recipe.appleId, Blogger.id == Blog.bloggerId),
            viewonly=True)
})

但每当我做以下事情时:

Apple.appleBloggers = relationship(Blogger, 
    secondary=join(Recipe, Blog, Recipe.id==Blog.recipeId),
    primaryjoin= Apple.id == Recipe.appleId,
    secondaryjoin= Blog.bloggerId == Blogger.id)

我收到错误:

apple = Apple(name="RedDelicious")
session.add(apple)
session.commit()
print(apple.appleBloggers)

1 个答案:

答案 0 :(得分:1)

您正在混合声明性和经典映射。分配type之类仅适用于声明性。在经典映射中执行此操作的正确方法是:

immutable

替代解决方案(带有映射对象):

relationship