我想使用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"
编辑:澄清的架构前缀
答案 0 :(得分:2)
但我的PostgreSQL数据库中的表是故意的。这意味着mytable存在,但“mytable”不存在。
你误解了引用的内容。在你的情况下(即表名中没有特殊字符的情况),双引号唯一的做法是使名称区分大小写。如果您的表名为MyTable
,那么
SELECT * FROM mytable;
有效,因为它在
时不区分大小写SELECT * FROM "mytable";
不是因为它区分大小写。然而
SELECT * FROM "MyTable";
会起作用,这就是你要找的东西。
另一个问题(如评论中的@IljaEverilä所述)是:
SELECT * FROM "myschema.mytable"
哪个postgres视为名为myschema.mytable
的表,因为你引用了整个事情。我认为这就是你要找的东西:
SELECT * FROM "myschema"."mytable"
即。您需要一个单独的模式标识符,并为.
加入的表分开。
答案 1 :(得分:1)
施工
sql.Identifier('myschema.mytable')
被视为单个quoted identifier,从生成的查询中可以看出。您应该将架构和表名称作为单独的标识符传递给格式:
cursor.execute(sql.SQL("SELECT * FROM {}.{}").format(
sql.Identifier('myschema'),
sql.Identifier('mytable'))
请注意,架构和表名称必须完全匹配,大小写和所有内容,因为psycopg2
SQL string composition tools生成带引号的标识符,带引号的标识符区分大小写。