Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQLAlchemy渴望加入关系不起作用_Python_Sql_Sqlalchemy - Fatal编程技术网

Python SQLAlchemy渴望加入关系不起作用

Python SQLAlchemy渴望加入关系不起作用,python,sql,sqlalchemy,Python,Sql,Sqlalchemy,我为多语言数据库设计将表分为post和post_翻译 还将表分隔为标签和post_标签 并将tag_idFK链接到tags表 在本例中,我必须提取包含特定标记名的所有帖子 class Post(Base): __tablename__ = 'posts' id = Column(BigInteger, primary_key=True, autoincrement=True) names = relationship('PostTranslation', backre

我为多语言数据库设计将表分为post和post_翻译

还将表分隔为标签和post_标签

并将tag_idFK链接到tags表

在本例中,我必须提取包含特定标记名的所有帖子

class Post(Base):
    __tablename__ = 'posts'

    id = Column(BigInteger, primary_key=True, autoincrement=True)

    names = relationship('PostTranslation', backref='posts')
    tags = relationship('PostTag', backref='posts')


class Language(Base):
    __tablename__ = 'languages'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    lang = Column(Unicode(255), nullable=False)


class Tag(Base):
    __tablename__ = 'tags'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(Unicode(255), nullable=False)


class PostTranslation(Base):
    __tablename__ = 'post_translation'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    post_id = Column(BigInteger, ForeignKey('posts.id'))
    language_id = Column(BigInteger, ForeignKey('languages.id'))
    title = Column(Unicode(255), nullable=False)

    post = relationship('Post', uselist=False)
    language = relationship('Language', uselist=False)


class PostTag(Base):
    __tablename__ = 'post_tags'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    post_id = Column(BigInteger, ForeignKey('posts.id'))
    tag_id = Column(BigInteger, ForeignKey('tags.id'))
    language_id = Column(BigInteger, ForeignKey('languages.id'))

    post = relationship('Post', uselist=False)
    language = relationship('Language', uselist=False)
    tag = relationship('Tag', uselist=False)
上面的代码工作得很好。但是当我记录查询时

    query = session.query(PostTag).options(
        joinedload(PostTag.post).joinedload(Post.names)
    ).join(Tag).filter(Tag.name == 'python').options(
        contains_eager(PostTag.tag)
    ).all()

    for q in query:
        print(q.post.tags)
正如您所知,访问标记时出现了N+1问题。q、 邮政标签

我不知道为什么查询再次发生,尽管已经连接并急切地加载了表中的标记

这里有什么解决办法吗

谢谢。

问题解决了

使用子查询进行求解

2020-01-30 20:25:45,854 INFO sqlalchemy.engine.base.Engine SELECT tags.id AS tags_id, tags.name AS tags_name, post_tags.id AS post_tags_id, post_tags.post_id AS post_tags_post_id, post_tags.tag_id AS post_tags_tag_id, post_tags.language_id AS post_tags_language_id, post_translation_1.id AS post_translation_1_id, post_translation_1.post_id AS post_translation_1_post_id, post_translation_1.language_id AS post_translation_1_language_id, post_translation_1.title AS post_translation_1_title, posts_1.id AS posts_1_id 
FROM post_tags INNER JOIN tags ON tags.id = post_tags.tag_id LEFT OUTER JOIN posts AS posts_1 ON posts_1.id = post_tags.post_id LEFT OUTER JOIN post_translation AS post_translation_1 ON posts_1.id = post_translation_1.post_id 
WHERE tags.name = %(name_1)s
2020-01-30 20:25:45,854 INFO sqlalchemy.engine.base.Engine {'name_1': 'python'}
2020-01-30 20:25:45,856 INFO sqlalchemy.engine.base.Engine SELECT post_tags.id AS post_tags_id, post_tags.post_id AS post_tags_post_id, post_tags.tag_id AS post_tags_tag_id, post_tags.language_id AS post_tags_language_id 
FROM post_tags 
WHERE %(param_1)s = post_tags.post_id
2020-01-30 20:25:45,856 INFO sqlalchemy.engine.base.Engine {'param_1': 1}
[<model.PostTag object at 0x10951a710>, <model.PostTag object at 0x109522b90>]
2020-01-30 20:25:45,857 INFO sqlalchemy.engine.base.Engine SELECT post_tags.id AS post_tags_id, post_tags.post_id AS post_tags_post_id, post_tags.tag_id AS post_tags_tag_id, post_tags.language_id AS post_tags_language_id 
FROM post_tags 
WHERE %(param_1)s = post_tags.post_id
2020-01-30 20:25:45,857 INFO sqlalchemy.engine.base.Engine {'param_1': 3}
from sqlalchemy import func


sub1 = session.query(Tag.id).filter(Tag.name == 'python')
sub2 = session.query(PostTag.post_id).filter(PostTag.tag_id.in_(sub1))

q = session.query(
    func.group_concat(PostTranslation.title.distinct()).label('title'),
    PostTag.post_id.label('id'),
    func.group_concat(Tag.name).label('tags'),
).join(
    Tag, Tag.id == PostTag.tag_id
).join(
    PostTranslation,
    PostTranslation.post_id == PostTag.post_id,
).filter(
    PostTag.post_id.in_(sub2),
).group_by(
    PostTag.post_id,
    PostTranslation.title,
).all()