python - sqlalchemy 在多个表上联接和排序

标签 python sql postgresql sqlalchemy

我正在使用一个具有如下关系的数据库:

    class Source(Model):
       id = Identifier()

    class SourceA(Source):
       source_id = ForeignKey('source.id', nullable=False, primary_key=True)
       name = Text(nullable=False)

    class SourceB(Source):
       source_id = ForeignKey('source.id', nullable=False, primary_key=True)
       name = Text(nullable=False)

    class SourceC(Source, ServerOptions):
       source_id = ForeignKey('source.id', nullable=False, primary_key=True)
       name = Text(nullable=False)

我想要做的是连接所有表 Source、SourceA、SourceB、SourceC,然后连接 order_by 名称。

对我来说听起来很容易,但我已经为此烦恼了一段时间,而且我的头开始疼了。另外,我对 SQL 或 sqlalchemy 不是很熟悉,因此浏览了很多文档,但无济于事。也许我只是没有看到它。 This尽管与比我可用的更新版本相关(请参阅下面的版本),但似乎很接近。

我觉得很接近,但这并不意味着什么。这是我的最新尝试,在 order_by 调用之前看起来不错。

    Sources = [SourceA,  SourceB, SourceC]
    # list of join on Source
    joins = [session.query(Source).join(source) for source in Sources]
    # union the list of joins
    query = joins.pop(0).union_all(*joins)
据我所知,query 在这一点上似乎是正确的,即 query.all() 有效。所以现在我尝试应用 order_by ,它在调用 .all 之前不会抛出错误。

尝试1:我只使用我想要的属性

    query.order_by('name').all()
    # throws sqlalchemy.exc.ProgrammingError: (ProgrammingError) column "name" does not exist

尝试2:我只使用我想要的定义的列属性

    query.order_by(SourceA.name).all()
    # throws sqlalchemy.exc.ProgrammingError: (ProgrammingError) missing FROM-clause entry for table "SourceA"

很明显吗?我缺少什么?谢谢!

版本:

sqlalchemy.版本 = '0.8.1'

(PostgreSQL)9.1.3

编辑 我正在处理一个需要查询对象句柄的框架。我有一个裸查询似乎可以完成我想要的任务,但我仍然需要将其包装在查询对象中。不确定这是否可能。谷歌搜索...

select = """
    select s.*, a.name from Source d inner join SourceA a on s.id = a.Source_id
    union
    select s.*, b.name from Source d inner join SourceB b on s.id = b.Source_id
    union
    select s.*, c.name from Source d inner join SourceC c on s.id = c.Source_id
    ORDER BY "name";
"""
selectText = text(select)
result = session.execute(selectText)
# how to put result into a query. maybe Query(selectText)? googling...
result.fetchall():

最佳答案

假设coalesce函数足够好,下面的示例应该为您指明方向。一个选项自动创建子列表,而另一个选项是显式的。

这不是您在编辑中指定的查询,但您可以排序(您的原始请求):

def test_explicit():
    # specify all children tables to be queried
    Sources = [SourceA, SourceB, SourceC]
    AllSources = with_polymorphic(Source, Sources)

    name_col = func.coalesce(*(_s.name for _s in Sources)).label("name")
    query = session.query(AllSources).order_by(name_col)
    for x in query:
        print(x)


def test_implicit():
    # get all children tables in the query
    from sqlalchemy.orm import class_mapper
    _map = class_mapper(Source)
    Sources = [_smap.class_
               for _smap in _map.self_and_descendants
               if _smap != _map  # @note: exclude base class, it has no `name`
               ]
    AllSources = with_polymorphic(Source, Sources)

    name_col = func.coalesce(*(_s.name for _s in Sources)).label("name")
    query = session.query(AllSources).order_by(name_col)
    for x in query:
        print(x)

关于python - sqlalchemy 在多个表上联接和排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28467416/

相关文章:

sql - 列的默认值(当值设置为 NULL 时)等于其他列

python - 向 urllib.request.read 传递字符串但获取字节属性错误

python - Django 表格 : reasons to use them?

java - 为什么 Oracle Pivot 产生不存在的结果?

sql - 如何处理 DATEDIFF(MINUTE, '00:00' , '24:20' ) 类似场景?

postgresql - 更新 postgres jsonb 列

sql - 在 Postgresql 中拆分以逗号分隔的字段并对所有结果表执行 UNION ALL

python - 我无法使用 docker-compose 对 MySQL 和 Django App 进行 Dockerize

Python打印二进制值及其十进制形式

sql - 异步服务器,在等待回调时处理断开连接