当前位置: 首页 > 面试题库 >

SQLAlchemy包含与join和contains_eager的空关系

柴砚文
2023-03-14
问题内容

我有2个模型Recording和Recording_results像这样

class Recording(Base):
    __tablename__ = 'recordings'

    id = Column(Integer, primary_key=True)
    filename = Column(String, nullable=False)

    language_id = Column(Integer, ForeignKey('languages.id'), nullable=False)
    language = relationship("Language", back_populates="recordings")

    user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    user = relationship("User", back_populates="recordings")

    created_at = Column(DateTime, nullable=False, default=func.now())
    updated_at = Column(DateTime, nullable=False,
                        default=func.now(), onupdate=func.now())
    deletedd_at = Column(DateTime, nullable=True)

    def __repr__(self):
        return 'id: {}'.format(self.id)

User.recordings = relationship("Recording", order_by=Recording.id, back_populates="user")
Language.recordings = relationship("Recording", order_by=Recording.id, back_populates="language")


class RecordingResult(Base):
    __tablename__ = 'recording_results'

    id = Column(Integer, primary_key=True)
    is_with_dictionary = Column(Boolean, default=False)
    result = Column(String, nullable=True)
    run_time = Column(Float, default=0.0)

    recording_id = Column(Integer, ForeignKey('recordings.id'), nullable=False)
    recording = relationship("Recording", back_populates="recording_results", lazy="joined")

    speech_service_id = Column(Integer, ForeignKey('speech_services.id'), nullable=False)
    speech_service = relationship("SpeechService", back_populates="recording_results")

    created_at = Column(DateTime, nullable=False, default=func.now())
    updated_at = Column(DateTime, nullable=False,
                        default=func.now(), onupdate=func.now())
    deletedd_at = Column(DateTime, nullable=True)

    def __repr__(self):
        return 'id: {}'.format(self.id)

Recording.recording_results = relationship("RecordingResult", order_by="desc(RecordingResult.id)", back_populates="recording", lazy="joined")
SpeechService.recording_results = relationship("RecordingResult", order_by=RecordingResult.id, back_populates="speech_service")

我需要获取其中不包含record_results并具有条件的记录项目列表(Recording.user_id ==
id,Recording.deletedd ==无,RecordingResult.deletedd ==无)

我用这个查询

db.session.query(Recording).filter(Recording.user_id == id, Recording.deletedd_at == None).order_by(Recording.id.desc()).join(Recording.recording_results).options(contains_eager(Recording.recording_results)).filter(RecordingResult.deletedd_at == None).all()

并且它过滤掉了,但似乎join方法不包括具有空recording_results关系的录制

我使用棉花糖将结果打印到json

我的结果:

{
        "id": 4,
        "filename": "15615378415768423_test.txt",
        "language_id": 1,
        "user_id": 2,
        "recording_results": [
            {
                "id": 5,
                "is_with_dictionary": true,
                "result": "test5",
                "run_time": 1200.2,
                "recording_id": 4,
                "speech_service_id": 2
            }
        ],
        "created_at": "2019-06-26T08:30:41.591410+00:00"
    },
    {
        "id": 2,
        "filename": "15615371606083994_test.txt",
        "language_id": 2,
        "user_id": 2,
        "recording_results": [
            {
                "id": 1,
                "is_with_dictionary": true,
                "result": "test1",
                "run_time": 1500.2,
                "recording_id": 2,
                "speech_service_id": 4
            },
            {
                "id": 2,
                "is_with_dictionary": false,
                "result": "test2",
                "run_time": 1600.2,
                "recording_id": 2,
                "speech_service_id": 3
            }
        ],
        "created_at": "2019-06-26T08:19:20.628205+00:00"
    }

预期结果:

{
        "id": 5,
        "filename": "15616009750201173_test.txt",
        "language_id": 1,
        "user_id": 2,
        "recording_results": [],
        "created_at": "2019-06-27T02:02:55.035810+00:00"
    },
    {
        "id": 4,
        "filename": "15615378415768423_test.txt",
        "language_id": 1,
        "user_id": 2,
        "recording_results": [
            {
                "id": 5,
                "is_with_dictionary": true,
                "result": "test5",
                "run_time": 1200.2,
                "recording_id": 4,
                "speech_service_id": 2
            }
        ],
        "created_at": "2019-06-26T08:30:41.591410+00:00"
    },
    {
        "id": 2,
        "filename": "15615371606083994_test.txt",
        "language_id": 2,
        "user_id": 2,
        "recording_results": [
            {
                "id": 2,
                "is_with_dictionary": false,
                "result": "test2",
                "run_time": 1600.2,
                "recording_id": 2,
                "speech_service_id": 3
            },
            {
                "id": 1,
                "is_with_dictionary": true,
                "result": "test1",
                "run_time": 1500.2,
                "recording_id": 2,
                "speech_service_id": 4
            }
        ],
        "created_at": "2019-06-26T08:19:20.628205+00:00"
    }

如何在联接查询中也包括空关系?


问题答案:

一个INNER JOIN像由

join(Recording.recording_results)

仅当联接的两侧都存在匹配行时才会产生一行。

LEFT [OUTER] JOIN产生的AQuery.outerjoin()将在左侧包含行,而在右侧则没有匹配行,因此,如果没有其他使用右侧表的谓词,则更改联接类型会有所帮助。

实际上,您可以这样做,但是它确实是“有效的”,因为它是一种IS NULL检查。不过,ON在这种情况下,它的适当位置是子句:

outerjoin(RecordingResult, and_(Recording.recording_results, RecordingResult.deletedd_at == None))

取代的使用filter()



 类似资料:
  • 问题内容: 我正在学习SQLAlchemy表达式语言,并且正在尝试执行一个琐碎的查询,该查询通过以下方式返回单个重复的列: 哪个输出: 即,仅两个请求的列之一。我期望: 为了再次确认我的期望是正确的,我直接在sqlite3和PostgreSQL 9.2(下面的[1]和[2])中运行了等效的查询,这两个查询都正确地返回了重复的id。我正在使用SQLAlchemy版本0.8.0b2,Python3.2

  • 正在寻找旧JSF页面的解决方案。我试图使用contains方法根据另一列是否包含单词red box来呈现组合框。 这一个工作和组合框被禁用。 但是,我也想在值不包含红色框时渲染它们,但随后将启用combox。 这是行不通的。 因此,我如何测试的任何想法都不包含特定的单词。我还尝试了choose test when,但由于第一个表。col4值只是一个空字符串。 有什么想法吗?谢谢。

  • 我们也可以为相关联的实体甚至是对一个集合中的全部元素指定一个别名,这时要使用关键字 join。 from Cat as cat inner join cat.mate as mate left outer join cat.kittens as kitten from Cat as cat left join cat.mate.kittens as kittens from For

  • 问题内容: MSDN文档指出: COUNT(*)返回组中的项目数。这包括NULL值和重复项。 您如何在一个组中有一个空值?谁能解释他们要提出的观点? 问题答案: 如果你有这张桌子 表格1: 然后 输出为:

  • 问题内容: 我在这里阅读了很多关于stackoverflow和google的其他文章,但找不到解决方案。 当我将模型从CharField更改为ForeignKey时,一切都开始了。我收到的错误是: 我的模型如下: 之前不存在场所_国家/地区,因此迁移成功完成。但是,place_city是一个CharField。 我对迁移文件进行了一些更改,以便它将执行sql,如下所示: 提前致谢! 更新:我的新迁

  • 问题内容: 和之间有什么区别? 交叉加入: 内部联接: 哪一种更好,为什么我要使用其中一种呢? 问题答案: 交叉联接不会合并行,如果每个表中有100行且1对1匹配,您将得到10.000个结果,Innerjoin在相同情况下将仅返回100行。 这两个示例将返回相同的结果: 交叉联接 内部联接 使用最后一种方法