Python psycopg2 возвращает False, когда pgadmin возвращает True - PullRequest
0 голосов
/ 25 января 2020

У меня есть функция python, в которой я хочу проверить, существует ли таблица PostgreSQL или нет (True, False)

она не возвращает True ... даже когда я вошел в систему та же БД и проверка в PGAdmin4 .. и получение True.

Я пропустил коммит? Я попытался добавить commit() безрезультатно.

def __exists_table(self, table_name):
    cursor = self.__get_a_cursor()

    try:
        string_to_execute = "SELECT EXISTS(SELECT 1 FROM pg_catalog.pg_tables WHERE schemaname = 'public' AND tablename = '" + table_name + "');"

        cursor.execute(string_to_execute)

        query_results = cursor.fetchall()
        if len(query_results) > 1:
            print("__exists_data got back multiple results, using the first")
        query_results = query_results[0][0]

        return query_results
    except Exception as err:
        print("Exception on __exists_table: " + str(err))
        raise err
    finally:
        cursor.close()

1 Ответ

1 голос
/ 25 января 2020

Ваш код работает как написано.

У меня есть база данных, содержащая одну таблицу, table1:

$ psql -h localhost
psql (11.6, server 12.1 (Debian 12.1-1.pgdg100+1))
Type "help" for help.

lars=> \d
        List of relations
 Schema |  Name  | Type  | Owner
--------+--------+-------+-------
 public | table1 | table | lars
(1 row)

Если я заверну ваш код в работающий скрипт Примерно так:

import psycopg2


class DBTest:
    def __init__(self):
        self.db = psycopg2.connect('host=localhost dbname=lars password=secret')

    def __get_a_cursor(self):
        return self.db.cursor()

    def __exists_table(self, table_name):
        cursor = self.__get_a_cursor()

        try:
            string_to_execute = "SELECT EXISTS(SELECT 1 FROM pg_catalog.pg_tables WHERE schemaname = 'public' AND tablename = '" + table_name + "');"

            cursor.execute(string_to_execute)

            query_results = cursor.fetchall()
            if len(query_results) > 1:
                print("__exists_data got back multiple results, using the first")
            query_results = query_results[0][0]

            return query_results
        except Exception as err:
            print("Exception on __exists_table: " + str(err))
            raise err
        finally:
            cursor.close()

    def test_exists_table(self, table_name):
        return self.__exists_table(table_name)


db = DBTest()
for table_name in ['table1', 'table2']:
    if db.test_exists_table(table_name):
        print(f'{table_name} exists')
    else:
        print(f'{table_name} does not exist')

Выполнение программы приводит к выводу, который я ожидал бы:

table1 exists
table2 does not exist

Сказав это, я внесу следующие изменения в ваш код. Во-первых, вместо создания строки запроса, подобной этой:

string_to_execute = """SELECT EXISTS(
  SELECT 1 FROM pg_catalog.pg_tables
  WHERE schemaname = 'public' 
    AND tablename = '""" + table_name + "');"

cursor.execute(string_to_execute)

Я бы позволил драйверу вашей базы данных позаботиться о замене параметров для вас:

string_to_execute = """SELECT EXISTS(
  SELECT 1 FROM pg_catalog.pg_tables
  WHERE schemaname = 'public' 
    AND tablename = %s
  )"""

cursor.execute(string_to_execute, (table_name,))

Это легче читать и безопаснее , поскольку он будет правильно заключать в кавычки любой специальный символ в параметре.

...