Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Базы данных
  • » Универсальная проверка на существование таблицы для разных реляционных БД [RSS Feed]

#1 Май 26, 2015 16:51:40

den1024
Зарегистрирован: 2014-03-28
Сообщения: 27
Репутация: +  0  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

Приветствую Всех!

Подскажите, пожалуйста, каким способом из скрипта на 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()


Но вот как произвести проверку если я не знаю какая СУБД используется в данный момент?
Был бы очень благодарен за пример кода!

Офлайн

#2 Май 26, 2015 17:33:43

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

den1024
мы не знаем какая БД в данный момент используется
А подкиньте идей, как такое может быть?



Офлайн

#3 Май 26, 2015 17:46:14

den1024
Зарегистрирован: 2014-03-28
Сообщения: 27
Репутация: +  0  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

Функция которая проводит проверку - работает с курсором. И данной функции дозволено использовать в запросах только стандарт ANSI.

Понятно, что можно передавать тип БД и потом if … elif'ами делать подстановку на проверку ошибок. Но возможно есть более простой (универсальный) вариант?

Офлайн

#4 Май 26, 2015 18:26:56

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

Не понял, в вашей программе уже есть тип БД, иначе как вы создаете коннект к базе и курсор.
Если вы знаете тип БД, что может быть проще чем просто его использовать?



Офлайн

#5 Май 27, 2015 00:26:01

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 8667
Репутация: +  770  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

den1024
если подразумевается, что мы не знаем какая БД в данный момент используется?
Используй шаблон Стратегия. (Посмотришь там пример на питоне.)
У тебя должен быть обработчик для каждой СУБД. В каждом обработчике порождаются свои исключения, которые отлавливаются и транслируются в общие исключения.



Отредактировано py.user.next (Май 27, 2015 00:27:39)

Офлайн

#6 Май 27, 2015 11:20:19

den1024
Зарегистрирован: 2014-03-28
Сообщения: 27
Репутация: +  0  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

Премного благодарен за информацию по шаблону Стратегия.

Еще один вопрос - как можно разобрать обычный 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 может и не быть?

Офлайн

#7 Май 27, 2015 19:12:02

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 8667
Репутация: +  770  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

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()

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

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



Отредактировано py.user.next (Май 27, 2015 19:16:00)

Офлайн

#8 Май 28, 2015 06:21:06

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

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



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#9 Май 28, 2015 07:57:50

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 8667
Репутация: +  770  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

PooH
Если PGressHandler реализует некий абстрактный интерфейс DBHandler
PGressHandler - это конкретный исполнитель.
Интерфейсом (шаблоном ООП) это было бы, если бы оно только задавало способ обращения с чем-то. И абстрактным интерфейсом - если бы его можно было использовать только для того, чтобы от него производить конкретные интерфейсы. Можно, конечно, нагородить огород из всяких шаблонов, но когда он их допишет, то уже забудет, для чего это всё надо было. :)

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



Отредактировано py.user.next (Май 28, 2015 07:59:17)

Офлайн

#10 Май 28, 2015 09:35:39

den1024
Зарегистрирован: 2014-03-28
Сообщения: 27
Репутация: +  0  -
Профиль   Отправить e-mail  

Универсальная проверка на существование таблицы для разных реляционных БД

py.user.next

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

Но ещё такой вопрос по теме - как проверять на существование таблицы в БД? Есть ли универсальный способ (DB API?) или в каждой БД по своему?

Офлайн

  • Начало
  • » Базы данных
  • » Универсальная проверка на существование таблицы для разных реляционных БД[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version