我正在使用具有以下关系的数据库:
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.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():
答案 0 :(得分:1)
假设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)
答案 1 :(得分:0)
您的第一次尝试听起来不起作用,因为Source中没有名称,这是查询的根表。此外,在您加入后会有多个名称列,因此您需要更具体。尝试
query.order_by('SourceA.name').all()
至于你的第二次尝试,什么是ServerA?
query.order_by(ServerA.name).all()
可能是一个错字,但不确定它是针对SO还是您的代码。尝试:
query.order_by(SourceA.name).all()