Найти - Пользователи
Полная версия: Универсальная проверка на существование таблицы для разных реляционных БД
Начало » Базы данных » Универсальная проверка на существование таблицы для разных реляционных БД
1 2 3
den1024
Приветствую Всех!

Подскажите, пожалуйста, каким способом из скрипта на python 3.4 можно проверить существование таблицы в БД если подразумевается, что мы не знаем какая БД в данный момент используется?

Ранее для postgres я проверял отработку по номеру Exception:

try:
            # Выполняем запрос на выборку из таблицы (SELECT)
            curs.execute(query)
            self.conn.commit()
        except psycopg2.Error as e:
            self.conn.rollback()
            if e.pgcode == '42P01':  # Если получаем данную ошибку - таблица не существует
                return 'notTable', 'OK'
            else:
                error_message = "Error while searching table in the database in function is_object_table: " + e.pgerror
                return 'False', error_message
        finally:
            curs.close()


Но вот как произвести проверку если я не знаю какая СУБД используется в данный момент?
Был бы очень благодарен за пример кода!
FishHook
den1024
мы не знаем какая БД в данный момент используется
А подкиньте идей, как такое может быть?
den1024
Функция которая проводит проверку - работает с курсором. И данной функции дозволено использовать в запросах только стандарт ANSI.

Понятно, что можно передавать тип БД и потом if … elif'ами делать подстановку на проверку ошибок. Но возможно есть более простой (универсальный) вариант?
FishHook
Не понял, в вашей программе уже есть тип БД, иначе как вы создаете коннект к базе и курсор.
Если вы знаете тип БД, что может быть проще чем просто его использовать?
py.user.next
den1024
если подразумевается, что мы не знаем какая БД в данный момент используется?
Используй шаблон Стратегия. (Посмотришь там пример на питоне.)
У тебя должен быть обработчик для каждой СУБД. В каждом обработчике порождаются свои исключения, которые отлавливаются и транслируются в общие исключения.
den1024
Премного благодарен за информацию по шаблону Стратегия.

Еще один вопрос - как можно разобрать обычный Exception при использовании разных БД?

Когда я работаю с postgres, код обработки исключения (который я использую для определения существует ли таблица или нет) выглядит так:

 except psycopg2.Error as e:
            self.conn.rollback()
            if e.pgcode == '42P01':  # Если получаем данную ошибку - таблица не существует
                return 'notTable', 'OK'
            else:
                error_message = "Error while searching table in the database in function is_object_table: " + e.pgerror
                return 'False', error_message
        finally:
            curs.close()

Но если я использую:

except Exception as e:

То как быть в данном случае? Ведь уже атрибута pgcode может и не быть?
py.user.next
den1024
Еще один вопрос - как можно разобрать обычный Exception при использовании разных БД?
Не нужно ловить Exception, оно используется для создания производных исключений.

den1024
Когда я работаю с postgres, код обработки исключения (который я использую для определения существует ли таблица или нет) выглядит так:
Это ерунда.

Вот пример фрагмента:
class PGressError(Exception):
    pass
 
class PGressNoDbError(PGressError):
    pass
 
class PGressNoTableError(PGressError):
    pass
 
class PGressHandler:
    
    def connect(self, host, port, user, password):
        pass
    
    def select_db(self, name):
        if not self.has_db(name):
            raise PGressNoDbError('no such database')
    
    def has_db(self, name):
        return False    
    
    def create_table(self, name):
        pass
        
    def disconnect(self):
        pass
 
pgress = PGressHandler()
pgress.connect('h', 'p', 'u', 'p')
pgress.select_db('x')
pgress.disconnect()

Сначала создаёшь общее исключение для СУБД, потом на его основе создаёшь конкретные исключения, потом порождаешь их в соотвествующих ситуациях.

А в стратегии ты их отлавливаешь, и порождаешь общие исключения для всех СУБД.
PooH
py.user.next
Сначала создаёшь общее исключение для СУБД, потом на его основе создаёшь конкретные исключения, потом порождаешь их в соотвествующих ситуациях.
А в стратегии ты их отлавливаешь, и порождаешь общие исключения для всех СУБД.
Если PGressHandler реализует некий абстрактный интерфейс DBHandler, то не проще ли в нем сразу бросать обобщенные исключения, наследники DBError - DBNoDbError, DBNoTableError?
py.user.next
PooH
Если PGressHandler реализует некий абстрактный интерфейс DBHandler
PGressHandler - это конкретный исполнитель.
Интерфейсом (шаблоном ООП) это было бы, если бы оно только задавало способ обращения с чем-то. И абстрактным интерфейсом - если бы его можно было использовать только для того, чтобы от него производить конкретные интерфейсы. Можно, конечно, нагородить огород из всяких шаблонов, но когда он их допишет, то уже забудет, для чего это всё надо было. :)

PooH
то не проще ли в нем сразу бросать обобщенные исключения, наследники DBError
Если какое-то не будет отловлено сверху (например, оно есть, но его обработка не нужна), а исполнителей будет множество и каждый со своим набором исключений, то должен быть способ знать, чьё исключение было порождено, чтобы не запутаться.
den1024
py.user.next

Большое спасибо за пример по исключениям!

Но ещё такой вопрос по теме - как проверять на существование таблицы в БД? Есть ли универсальный способ (DB API?) или в каждой БД по своему?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB