【问题标题】:Schema names in psycopg2 identifierspsycopg2 标识符中的模式名称
【发布时间】:2018-06-05 09:45:47
【问题描述】:

我想用psycopg2的sql子模块写干净的动态SQL:

from psycopg2 import sql
...
cursor.execute(sql.SQL("SELECT * FROM {}").format(sql.Identifier('myschema.mytable'))

这将创建以下查询:

SELECT * FROM "myschema.mytable"

这里我得到一个Relation "myschema.mytable" not found. 异常。

如何正确处理架构名称?以下语句可行,但我如何使用 psycopg2 创建它们?

SELECT * FROM myschema.mytable
SELECT * FROM myschema."mytable"
SELECT * FROM "myschema"."mytable"

编辑:阐明架构前缀

【问题讨论】:

  • 我刚刚在 DBeaver 中尝试过:SELECT * FROM mytable; 工作正常,而SELECT * FROM "mytable"; 出现错误。我必须添加 mytable 包含架构前缀,这可能会导致问题。

标签: python postgresql psycopg2


【解决方案1】:

建筑

sql.Identifier('myschema.mytable')

被视为单个quoted identifier,从生成的查询中可以看出。您应该将架构和表名作为单独的标识符传递给格式:

cursor.execute(sql.SQL("SELECT * FROM {}.{}").format(
    sql.Identifier('myschema'),
    sql.Identifier('mytable'))

请注意,架构和表名必须完全匹配,大小写和所有,因为psycopg2SQL string composition tools 产生带引号的标识符,而带引号的标识符区分大小写。

【讨论】:

    【解决方案2】:

    但是我的 PostgreSQL 数据库中的表是故意不加引号的。这意味着 mytable 存在,但“mytable”不存在。

    您误解了引号的作用。在您的情况下(即表名中没有特殊字符的情况下),双引号唯一能做的就是使名称区分大小写。如果您有名称为MyTable 的表,那么

    SELECT * FROM mytable;
    

    有效,因为它不区分大小写,而

    SELECT * FROM "mytable";
    

    不,因为它区分大小写。不过

    SELECT * FROM "MyTable";
    

    会起作用,这就是你要找的。​​p>


    另一个问题(正如 @IljaEverilä 在 cmets 中指出的那样)是:

    SELECT * FROM "myschema.mytable"
    

    哪个 postgres 将其视为名称为 myschema.mytable 的表,因为您已经引用了整个内容。我想这就是你要找的东西:

    SELECT * FROM "myschema"."mytable"
    

    即您需要单独的架构标识符和单独的由. 连接的表。

    【讨论】:

    • 感谢您的解释!
    猜你喜欢
    • 2022-01-20
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    相关资源
    最近更新 更多