【发布时间】:2018-10-28 13:58:04
【问题描述】:
这是架构:
post_tag = Table("post_tag", Base.metadata,
Column("post_id", Integer, ForeignKey("post.id")),
Column("tag_id ", Integer, ForeignKey("tag.id")))
class Post(Base):
id = Column(Integer, primary_key=True)
tags = relationship("Tag", secondary=post_tag, backref="post", cascade="all")
collection_id = Column(Integer, ForeignKey("collection.id"))
class Tag(Base):
id = Column(Integer, primary_key=True)
description = Column("description", UnicodeText, nullable=False, default="")
post_id = Column(Integer, ForeignKey("post.id"))
class Collection(Base):
id = Column(Integer, primary_key=True)
title = Column(Unicode(128), nullable=False)
posts = relationship("Post", backref="collection", cascade="all,delete-orphan")
tags = column_property(select([Tag])
.where(and_(Post.collection_id == id, Tag.post_id == Post.id))
.correlate_except(Tag))
基本上,Post 到 Tag 是多对多,Collection 到 Post 是一对多。
我想 Collection.tags 返回一组不同的帖子标签集。
但是,当我访问Collection.tags 时出现以下错误:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) 对于作为表达式一部分的 SELECT 只允许一个结果
编辑
它生成的 SQL
SELECT (SELECT tag.id, tag.description, tag.post_id
FROM tag, post
WHERE post.collection_id = collection.id AND tag.post_id = post.id) AS anon_1, collection.id AS collection_id, collection.title AS collection_title
FROM collection
WHERE collection.id = 1
我认为 post_id = Column(Integer, ForeignKey("post.id")) 是错误的,因为 post_id 在 post_tag 中。但是,如果我将其更改为 post_tag.post_id,则会抛出 AttributeError: 'Table' object has no attribute 'post_id'
EDIT2
我改成
tags = column_property(select([Tag])
.where(and_(Post.collection_id == id, post_tag.c.post_id == Post.id,
post_tag.c.tag_id == Tag.id)))
虽然这有效
SELECT tag.id, tag.description, tag.category_id, tag.post_id
FROM tag, post, post_tag
WHERE post.collection_id = 1 AND post_tag.post_id = post.id AND post_tag.tag_id = tag.id
但 SQLAlchemy 生成的查询没有
SELECT (SELECT tag.id, tag.description, tag.category_id, tag.post_id
FROM tag, post, post_tag
WHERE post.collection_id = collection.id AND post_tag.post_id = post.id AND post_tag.tag_id = tag.id) AS anon_1
FROM collection
WHERE collection.id = 1
【问题讨论】:
-
我认为您需要向我们展示给出错误的 SQL(或生成它的代码)。这通常意味着查询有
where mycol = (select ...),而select意外返回多行。 -
可能是表达式上下文中使用的
Collection.tags属性。它应该是一个带有自定义连接的关系属性。 -
@BoarGules 我发现了问题,但我不知道如何在 SQLAlchemy 中解决它。你能看看我的编辑吗?我认为问题在于我试图使用
column_property返回一个列表而不是单个值。
标签: python database sqlite sqlalchemy flask-sqlalchemy