【问题标题】:psycopg2 - 'Relation does not exist' in Postgresql databasepsycopg2 - Postgresql 数据库中的“关系不存在”
【发布时间】:2019-12-05 14:51:39
【问题描述】:

我试图弄清楚为什么我不能使用 psycopg2 访问 PostgreSQL 数据库中的特定表。我正在运行 PostgreSQL 11.5

如果我这样做,我可以连接到有问题的数据库并读取其中的所有表:

import psycopg2

try:
connection = psycopg2.connect(user = "postgres",                #psycopg2.connect() creates connection to PostgreSQL database instance
                              password = "battlebot",
                              host = "127.0.0.1",
                              port = "5432",
                              database = "BRE_2019")

cursor = connection.cursor()                                #creates a cursor object which allows us to execute PostgreSQL commands through python source

#Print PostgreSQL version
cursor.execute("""SELECT table_name FROM information_schema.tables
   WHERE table_schema = 'public'""")

for table in cursor.fetchall():
    print(table)

结果如下所示:

('geography_columns',)
('geometry_columns',)
('spatial_ref_sys',)
('raster_columns',)
('raster_overviews',)
('nc_avery_parcels_poly',)
('Zone5e',)
('AllResidential2019',)
#....etc....

我感兴趣的表格是最后一张,'AllResidential2019'

所以我尝试连接到它并通过执行以下操作打印内容:

try:
    connection = psycopg2.connect(user = "postgres",                
    #psycopg2.connect() creates connection to PostgreSQL database instance
                              password = "battlebot",
                              host = "127.0.0.1",
                              port = "5432",
                              database = "BRE_2019")

    cursor = connection.cursor()                                #creates a cursor object which allows us to execute PostgreSQL commands through python source

    cursor.execute("SELECT * FROM AllResidential2019;")           #Executes a database operation or query. Execute method takes SQL query as a parameter. Returns list of result
    record = cursor.fetchall()

    print(record)


except (Exception, psycopg2.Error) as error:
    print("Error while connecting to PostgreSQL: ", error)

我收到以下错误:

Error while connecting to PostgreSQL:  relation "allresidential2019" does not exist
LINE 1: SELECT * FROM AllResidential2019;

但是,当我尝试连接到我拥有的另一个数据库中的另一个表时,我可以成功连接并获得结果(这可行!结果就是该表中的数据):

try:
    connection = psycopg2.connect(user = "postgres",                #psycopg2.connect() creates connection to PostgreSQL database instance
                              password = "battlebot",
                              host = "127.0.0.1",
                              port = "5432",
                              database = "ClimbingWeatherApp") .  #different database name

    cursor = connection.cursor()                                


    cursor.execute("SELECT * FROM climbing_area_info ;")          
    record = cursor.fetchall()

    print(record)


except (Exception, psycopg2.Error) as error:
    print("Error while connecting to PostgreSQL: ", error)

我不明白为什么我可以使用完全相同的代码从一个表而不是另一个表中检索信息(名称是更改除外)。而且我也不知道如何解决这个问题。谁能给点建议?

【问题讨论】:

  • 你的错误没有提到:关系不存在。您似乎在表名周围使用单引号。请确认错误源自您发布的确切代码。如果您处于不同的试运行之间,请尝试再运行一次。我看到使用了 F 字符串(未在 climbing_area_info 中完成)但没有占位符大括号 {...}.
  • @Parfait 我稍微编辑了代码,谢谢。错误消息显示“关系不存在”,而不是语法错误。我尝试将语法稍微编辑为:'AllResidential2019'、AllResidential2019、public.AllResidential2019 和 public.'AllResidential2019'。
  • 通常“public”总是在 search_path 上,但你能检查一下你的情况“public”是否在搜索路径中。 show search_path;

标签: python python-3.x postgresql psycopg2


【解决方案1】:

您的表名区分大小写,您必须用双引号将其关闭:

SELECT * FROM "AllResidential2019";

在 Python 程序中可能如下所示:

cursor.execute('SELECT * FROM "AllResidential2019"')

或者你可以使用专用模块SQL string composition:

from psycopg2 import sql

# ...

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

请注意,区分大小写的 Postgres 标识符(即表、列、视图、函数等的名称)不必要地使简单的事情复杂化。我建议你不要使用它们。

【讨论】:

  • 就是这样,我需要使用双引号“”。谢谢!
【解决方案2】:

您的问题的原因很可能是 Postgres 的引用规则,该规则遵循关于双引号标识符的 ANSI SQL 标准。在创建表格时,您可能引用了表格:

CREATE TABLE "AllResidential2019" (
   ...
)

由于至少一个大写字母区分大小写,这要求您在引用表格时始终引用表格。请记住:单引号和双引号在 SQL 中具有不同的含义,而不是在 Python 中大部分可以互换。

SELECT * FROM "AllResidential2019"
DELETE FROM "AllResidential2019" ...
ALTER TABLE "AllResidential2019" ...

如果您的表、列或其他标识符不包含特殊字符、空格或reserved words,通常建议始终使用小写字母或不使用引号:

CREATE TABLE "allresidential2019" (
   ...
)

CREATE TABLE AllResidential2019 (
   ...
)

这样做,任何大写字母组合都可以使用

SELECT * FROM ALLRESIDENTIAL2019
SELECT * FROM aLlrEsIdEnTiAl2019
SELECT * FROM "allresidential2019"

查看有关该主题的进一步阅读:

【讨论】:

    猜你喜欢
    • 2021-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2012-08-27
    • 2017-06-26
    • 1970-01-01
    相关资源
    最近更新 更多