【问题标题】:Get PostgreSQL resultset column types without executing query using psycopg2在不使用 psycopg2 执行查询的情况下获取 PostgreSQL 结果集列类型
【发布时间】:2019-08-03 02:25:05
【问题描述】:

给定一个任意的 PostgreSQL 查询,例如SELECT * FROM (...) AS T,我怎样才能得到结果集的列名和类型没有实际使用 psycopg2 Python3 库执行查询?

我看到 JDBC solution 使用 getMetaData(),但我不知道如何在 psycopg2 中获取相同的信息。

PreparedStatement pstmt = con.prepareStatement("select ... ");
ResultSetMetaData meta = pstmt.getMetaData();
for (int i=1; i <= meta.getColumnCount(); i++) { ... }

【问题讨论】:

    标签: postgresql prepared-statement psycopg2


    【解决方案1】:

    据我了解,不执行(运行cur.execute())是不可能的

    但是,如果您想要使用 Psycopg2 可以用作查询的函数的 Postgres 解决方案,您可以使用此解决方案。如您所料,这将不执行您的查询,它只是创建一个临时的View,它允许我们使用目录information_schema.columns查询它的元数据

    CREATE OR REPLACE function define_query(query text) 
      RETURNS TABLE( column_name text,data_type text)  
    LANGUAGE plpgsql AS  
    $$ 
    DECLARE 
    v_view_n TEXT := 'temp_view$'; 
    BEGIN 
           EXECUTE format( 'CREATE OR REPLACE TEMP VIEW  %I AS %s', v_view_n,query);
           RETURN QUERY  select i.column_name::text, i.data_type ::text
               from information_schema.columns i where i.table_name = v_view_n;
    END $$;
    

    一旦你有了这个函数,你可以通过简单地调用这个函数而不是执行它来获得任何查询的定义。

    knayak=# select * from define_query('select 1::int as a,''TWO''::text as b');
     column_name | data_type
    -------------+-----------
     a           | integer
     b           | text
    (2 rows)
    

    【讨论】:

    • 有没有办法以某种方式分析准备好的语句,就像在 JDBC 代码中所做的那样?还有 Kaushik,谢谢你提供了一个详尽的例子,但是当我只需要分析它时,我真的对修改数据库感到不安(尤其是当我有只读访问权限或者我正在访问镜像时)
    • @Yurik :我可能没有明确提到,但这只是实现它的一种方式。如果有更好的选择,我会很高兴认识自己。就修改数据库而言,它只是创建了一个存储函数和一个临时视图(没有数据)。所以,不应该有不安的理由。
    • 谢谢,我只是担心在主从场景中,多个实例可能会因为创建相同的对象而发生冲突,而且在某些情况下,我会将数据库设置为只读以防止非数据更改导致意外数据损坏用户,因此此解决方案在这些情况下可能不起作用。
    • @Yurik :临时视图是为会话创建的,并在退出会话时自动删除。所以多个会话不应该产生问题。
    【解决方案2】:

    我认为您至少必须执行一些操作。

    如果您不希望返回任何行,您可以像select * from XXX where false 一样查询。此查询将向客户端返回 0 行的列类型。

    【讨论】:

    • 嘿,我很想以某种方式分析准备好的陈述或类似的东西......但是你的解决方案应该可以工作,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多