当前位置: 首页 > 知识库问答 >
问题:

使用SQLAlChemy从PostgreSQL行对象获取单个值

夔庆
2023-03-14

我将Python与SQLAlchemy(在我的特殊情况下是GeoAlchemy)一起使用,并且我有一个查询,该查询将生成一列行对象。我希望从这些行对象中提取特定的值,但是SQLAlchemy将行对象解释为单个实体(如果我正确的话,将它们作为字符串返回)。如何在不使用Python解析的情况下更清晰地返回这些单独的值?

我的真实生活用例:PostgreSQL的PostGIS扩展提供了一个名为ST_IsValidDetail的函数。此函数旨在返回一个valid_detail行,该行由布尔值有效、字符串原因和发生无效的几何位置组成。我已经放弃了PostGIS标签,因为我觉得这个问题比那个更普遍。我的查询类似于SELECTST_IsValidDetail('POINT(1 1)'::GEOMETRY);(当然是更复杂的几何)。

共有2个答案

章承基
2023-03-14

我从ST_IsValidDetail页面上的示例中找到了一种方法。显然,以下语法是有效的:

SELECT gid, reason(ST_IsValidDetail(the_geom)), ST_AsText(location(ST_IsValidDetail(the_geom)))

注意围绕函数调用的原因位置“调用”;ST_IsValidDetail返回的行中的列名称几乎被视为函数。事实证明,你可以欺骗SQLAlchemy做同样的事情。(假设session是先前设置的session对象,而db_geom是一个地质炼金术几何体对象。)

from sqlalchemy import func as sqlfunc
result = session.query(sqlfunc.reason(sqlfunc.ST_IsValidDetail(db_geom)), sqlfunc.ST_AsText(sqlfunc.location(sqlfunc.ST_IsValidDetail(db_geom)))).one()

result[0]将包含原因,result[1]将包含位置的WKT。(我们可以使用label给出列的实际名称。)

在不使用PostGIS功能的情况下对其进行修剪:

from sqlalchemy import func as sqlfunc
result = session.query(sqlfunc.columnname(sqlfunc.myrowfunc('some input string')).label('mylabel')).one()

这使得SQLAlChemy认为列名是一个函数,并以表单将SQL发送到数据库

SELECT columnname(myrowfunc('some input string')) AS mylabel;

我还没有尝试过它,但是如果有办法让SqLalCimy考虑我们的行是表,我们选择<代码>从< /代码>,这也可以工作。(请参见ST_IsValidDetail页面的最底部。)

华哲茂
2023-03-14

您可以使用:

SELECT (ST_IsValidDetail(the_value)).* FROM the_table;

... 但不幸的是,PostgreSQL实际上对每行执行一次ST_IsValidDetail函数。作为一种解决方法,您可以稍微修改查询,通过公共表表达式具体化,然后在第二次过程中提取元组:

WITH interim_result(v) AS (
    SELECT ST_IsValidDetail(the_value) FROM the_table
)
SELECT (v).* FROM interim_result;

(v)周围的参数需要告诉解析器您引用的是值,而不是表名。

演示:

CREATE OR REPLACE FUNCTION multirows(x IN integer, a OUT integer, b OUT integer, c OUT integer) AS
$$
BEGIN
    RAISE NOTICE 'multirows(%) invoked', x;
    a := x;
    b := x+1;
    c := x+2;
    RETURN;
END;
$$ LANGUAGE plpgsql;

craig=> SELECT multirows(x) FROM generate_series(1,2) x;
NOTICE:  multirows(1) invoked
NOTICE:  multirows(2) invoked
 multirows 
-----------
 (1,2,3)
 (2,3,4)
(2 rows)

craig=> SELECT (multirows(x)).* FROM generate_series(1,2) x;
NOTICE:  multirows(1) invoked
NOTICE:  multirows(1) invoked
NOTICE:  multirows(1) invoked
NOTICE:  multirows(2) invoked
NOTICE:  multirows(2) invoked
NOTICE:  multirows(2) invoked
 a | b | c 
---+---+---
 1 | 2 | 3
 2 | 3 | 4
(2 rows)




craig=> WITH interim(v) AS (SELECT multirows(x) FROM generate_series(1,2) x)
SELECT (v).* FROM interim;
NOTICE:  multirows(1) invoked
NOTICE:  multirows(2) invoked
 a | b | c 
---+---+---
 1 | 2 | 3
 2 | 3 | 4
(2 rows)
 类似资料:
  • 问题内容: 我有以下JSON,我需要使用JSONPath获得纯值: 我使用的表达式是,但是我总是得到一个数组: 而不是字符串值()。 问题答案: 但是我总是得到一个数组: 那是必然的。如您在本文档中所读,位于“结果”下(几乎在底部): 请注意,jsonPath的返回值是一个数组,也是一个有效的JSON结构。因此,您可能想再次将jsonPath应用于结果结构,或使用您喜欢的数组方法之一对其进行排序。

  • 问题内容: 我想确定显示点集合所需的最小面积。最简单的方法是像这样遍历整个集合: 我开始了解流。为此,您可以执行以下操作: 两者给出相同的结果。但是,尽管流方法很优雅,但速度却慢得多(如预期的那样)。 有没有办法让,,并在一个单一的流操作? 问题答案: 与类推,创建一个收集所需信息的类。它定义了两种方法:一种用于记录a的值,一种用于组合两个的值。 然后,您可以将收集到中。 更新 我完全对 OP得出

  • 我有以下数据库结构: 对于如何从April和May键获取对象的值,我有点困惑。使用*ngFor在对象上迭代时。我将所有关键点都作为对象。我试图使用,但不起作用。 完整代码: Html 输出 如上所述,我的数据现在位于下。那么,我如何避免或访问密钥以获取数据呢?是否可以使用?

  • 问题内容: 我有以下查询: 如何检查是否有行,如何只返回第一行(如果有匹配项,则只能返回一行)? 问题答案: 使用 得到之一,正是一个结果。在所有其他情况下,它将引发你可以处理的异常: 还有,它将为你提供可能的第一个结果,而不会引发这些异常。但是,由于你要处理没有结果或超出你的想象的情况,因此正是你应该使用的方法。

  • 我有一个方法返回<code>Single 我可以使用,但这不允许我从中返回列表。 我还尝试了。 编辑 我可以通过以下方式完成这项工作: 请告诉 如果这种方式是正确的 我是反应式编程新手,请解释一下。

  • 问题内容: 我有一个名为“ Test”的表,其中包含两个字段“ qnId”和“ Answers”。’qnId’存储一个uuid,’Answers’是一个jsonb数组,大致如下所示: 我该如何使用value来检索of的值。如何使用普通的SQL查询检索值 问题答案: 演示:db <>小提琴 您可以用来将数组元素扩展为每一行。之后,您可以使用运算符(文档)过滤正确的元素: