如何检查我在Python中连接到的Postgres数据库中是否存在列?

如何检查我在Python中连接到的Postgres数据库中是否存在列?,python,python-3.x,postgresql,psycopg2,Python,Python 3.x,Postgresql,Psycopg2,我在Python中使用postgres和库psycopg2。连接到数据库后,我尝试检查是否存在具有给定名称的表。在postgres中,我是通过以下几行来实现这一点的: \connect myDB select exists(select * from pg_tables where schemaname='public' AND tablename='mytable';) import psycopg2 as pg from psycopg2.extensions import ISOLATI

我在Python中使用postgres和库psycopg2。连接到数据库后,我尝试检查是否存在具有给定名称的表。在postgres中,我是通过以下几行来实现这一点的:

\connect myDB
select exists(select * from pg_tables where schemaname='public' AND tablename='mytable';)
import psycopg2 as pg
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT;
from psycopg2 import sql;

conn = pg.connect(user='postgres', host='localhost', password="pwd");
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT);
conn.autocommit = True
sql_table_check = sql.SQL("select exists(select * from pg_tables where schemaname='public' AND tablename={});")\
        .format(sql.Identifier("mytable"));
cur = conn.cursor()
如果表存在,也可以在表不存在的情况下使用。 在python中,我使用以下几行代码完成此操作:

\connect myDB
select exists(select * from pg_tables where schemaname='public' AND tablename='mytable';)
import psycopg2 as pg
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT;
from psycopg2 import sql;

conn = pg.connect(user='postgres', host='localhost', password="pwd");
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT);
conn.autocommit = True
sql_table_check = sql.SQL("select exists(select * from pg_tables where schemaname='public' AND tablename={});")\
        .format(sql.Identifier("mytable"));
cur = conn.cursor()
但这是返回错误

psycopg2.errors.UndefinedColumn: column "mytable" does not exist
LINE 1: ...m pg_tables where schemaname='public' AND tablename="mytable");
因为这样的表还没有创建

检查psycopg2中是否存在列的正确方法是什么

编辑


请注意,我想检查连接到的数据库中是否存在该表,我不介意它是否存在于另一个数据库中。

因此,您可以使用try和except检查错误以继续

sql_table_check = sql.SQL("select exists(select * from pg_tables where schemaname='public' AND tablename={});")\
        .format(sql.Identifier("mytable"));
try:
    cur = conn.cursor()
    print('Table exists')
except:
    print('Table does not exist')
根据评论编辑

您还可以捕获错误,以便稍后通过

sql_table_check = sql.SQL("select exists(select * from pg_tables where schemaname='public' AND tablename={});")\
        .format(sql.Identifier("mytable"));
try:
    cur = conn.cursor()
    print('Table exists')
except Exception as e:
    print(e)
    print('Table does not exist')
例如,简单地说,如果我们尝试:

try:
    a = 5 / 0
except Exception as e:
    print(e)
我们将获得输出

division by zero
您可以通过调试异常部分中的e内容来获得确切的格式字符串

因此,我们可以使用它来识别错误,再次使用,如:

try:
    a = a / 0
except Exception as e:
    print(e)
    if e.args[0] == 'division by zero':
        print('it is division by zero Error')
    else:
        raise(e)
因此,如果错误不是预期的,则会引发另一个错误

您可能会从psycopg2文档中获得错误异常,就像在https://docs.python.org/3/library/exceptions.html

如以下代码所示:

try:
    a = 5 / 0
except ZeroDivisionError:
    print('it is division by zero Error')
因此,我们得到:

it is division by zero Error
但当我们遇到另一个错误时,比如:

try:
    a = 5 / 0
except ZeroDivisionError:
    print('it is division by zero Error')
我们得到了另一个错误

NameError: name 'b' is not defined

所以,您可以使用try和except继续检查错误

sql_table_check = sql.SQL("select exists(select * from pg_tables where schemaname='public' AND tablename={});")\
        .format(sql.Identifier("mytable"));
try:
    cur = conn.cursor()
    print('Table exists')
except:
    print('Table does not exist')
根据评论编辑

您还可以捕获错误,以便稍后通过

sql_table_check = sql.SQL("select exists(select * from pg_tables where schemaname='public' AND tablename={});")\
        .format(sql.Identifier("mytable"));
try:
    cur = conn.cursor()
    print('Table exists')
except Exception as e:
    print(e)
    print('Table does not exist')
例如,简单地说,如果我们尝试:

try:
    a = 5 / 0
except Exception as e:
    print(e)
我们将获得输出

division by zero
您可以通过调试异常部分中的e内容来获得确切的格式字符串

因此,我们可以使用它来识别错误,再次使用,如:

try:
    a = a / 0
except Exception as e:
    print(e)
    if e.args[0] == 'division by zero':
        print('it is division by zero Error')
    else:
        raise(e)
因此,如果错误不是预期的,则会引发另一个错误

您可能会从psycopg2文档中获得错误异常,就像在https://docs.python.org/3/library/exceptions.html

如以下代码所示:

try:
    a = 5 / 0
except ZeroDivisionError:
    print('it is division by zero Error')
因此,我们得到:

it is division by zero Error
但当我们遇到另一个错误时,比如:

try:
    a = 5 / 0
except ZeroDivisionError:
    print('it is division by zero Error')
我们得到了另一个错误

NameError: name 'b' is not defined

我的回答是:

import psycopg2

con = psycopg2.connect("dbname=production host=localhost user=postgres")
tbl_sql = "SELECT count(*) FROM pg_tables WHERE schemaname='public' AND tablename= %s"
cur = con.cursor()
cur.execute(tbl_sql, ('cell_per',))
cur.fetchone()
(1,)

cur.execute(tbl_sql, ('cell_p',))
cur.fetchone()
(0,)


我的回答是:

import psycopg2

con = psycopg2.connect("dbname=production host=localhost user=postgres")
tbl_sql = "SELECT count(*) FROM pg_tables WHERE schemaname='public' AND tablename= %s"
cur = con.cursor()
cur.execute(tbl_sql, ('cell_per',))
cur.fetchone()
(1,)

cur.execute(tbl_sql, ('cell_p',))
cur.fetchone()
(0,)


为什么不从schemaname='public'和tablename='mytable'所在的pg_表中选择count*作为tbl\u ct,然后测试tbl\u ct>0?不要使用sql.Identifier作为表名。它是一个值而不是标识符。我是否要将字符串格式化为%s?请参阅下面的答案。为什么不从schemaname='public'和tablename='mytable'所在的pg_表中选择count*作为tbl\u ct,然后测试tbl\u ct>0?不要使用sql.Identifier作为表名。这是一个值而不是标识符。我是否要将字符串格式化为%s?请参阅下面的答案。我认为这不可靠,因为可能会生成其他不相关的异常。我不认为这是可靠的,因为可能会生成其他不相关的异常。这段代码有一个问题:如果另一个数据库中存在同名的表,但不存在在我连接到的数据库中,您的答案似乎是返回表存在。另外,我如何直接在postgres上运行此查询?@FrancescoBoi。pg_tables仅显示正在运行查询的数据库的表。要直接在psql中运行,请执行以下操作:从schemaname='public'和tablename=所在的pg_表中选择count*,或者您是否在要求其他内容?@AdrianKavler从我得到的结果来看,情况似乎并非如此。您正在运行的查询是什么,结果是什么?如果您得到的计数大于0,则该表位于数据库中。tbl_sql=从schemaname='public'和tablename=%s的pg_表中选择count*;cursor.executetbl_sql,'myTable',;游标。抓取一个。问题是它返回1,但myTable不是示例中连接到生产的数据库的表,而是另一个数据库的表。此代码有一个问题:如果另一个数据库中存在同名表,但我连接的数据库中不存在同名表,您的答案似乎是返回表存在。另外,我如何直接在postgres上运行此查询?@FrancescoBoi。pg_tables仅显示正在运行查询的数据库的表。要直接在psql中运行,请执行以下操作:从schemaname='public'和tablename=所在的pg_表中选择count*,或者您是否在要求其他内容?@AdrianKavler从我得到的结果来看,情况似乎并非如此。您正在运行的查询是什么,结果是什么?如果您得到的计数大于0,则该表位于数据库中。tbl_sql=从schemaname='public'和tablename=%s的pg_表中选择count*;cursor.executetbl_sql,'myTable',;游标。抓取一个。问题是它返回1,但myTable不是示例中连接到生产的数据库的表,而是另一个数据库的表。