Форум сайта python.su
всем привет!
пишу некий мигратор, делаю через класс … хочу чтобы для любой функции работающей с данными вначале выполнялось подключение к базе
пытаюсь сделать через декораторы… походу неправильно
import cx_Oracle import psycopg2 from configparser import ConfigParser class DbMigration2: # получение параметров подключений у обеих баз # из ini файла def __init__(self, settings): parser = ConfigParser() parser.read(settings) _conn_oracle_sett = {} _conn_postgres_sett = {} if parser.has_section('oracle') and parser.has_section('postgres'): params = parser.items('oracle') for param in params: _conn_oracle_sett[param[0]] = param[1] params = parser.items('postgres') for param in params: _conn_postgres_sett[param[0]] = param[1] else: raise Exception('Секции отсуствуют') self._conn_oracle_sett = _conn_oracle_sett self._conn_postgres_sett = _conn_postgres_sett def _connect_to_oracle(self): """ создание подключения к базе oracle """ self._dsn = cx_Oracle.makedsn(self._conn_oracle_sett["host"], self._conn_oracle_sett["port"], self._conn_oracle_sett["sid"]) self._oracle_conn = cx_Oracle.connect(self._conn_oracle_sett["user"], self._conn_oracle_sett["password"], self._dsn) def _connect_to_postgres(self): """ создание подключения к базе postgres """ self._conn_postgres_string = " ".join(["%s=%s" % (k, v) for k, v in self._conn_postgres_sett.items()]) # print(self._conn_string) self._postgres_conn = psycopg2.connect(self._conn_postgres_string) def postgres_connector(self, func): def wrapper(): self._connect_to_postgres() func() return wrapper def oracle_connector(self, func): def wrapper(): self._connect_to_oracle() func() return wrapper @postgres_connector @oracle_connector def export_abonents(self): """ Производит заливку лицевых счетов из БИТТл в таблицы хранилища """ try: # получаем лицевые счета абонентов из БИТТл or_cur = self._oracle_conn.cursor() sql = "select id from db.abonent" or_cur.execute(sql) # abns = [ abn[0] for abn in or_cur.fetchall()] abns = or_cur.fetchall() pg_cur = self._postgres_conn.cursor() # получаем список таблиц в которые будем заливать лицевые счета абонентов с БИТТл sql = "select table_name from storage.data_type dt where dt.base = %s" pg_cur.execute(sql, ("ABN", )) tables = [ tp[0] for tp in pg_cur.fetchall()] # обнуляем эти таблицы и заливаем туда лицевые счета for tbl in tables: sql = 'truncate table '+ tbl pg_cur.execute(sql) sql = "insert into "+ tbl +"(abonent_id) values(%s)" pg_cur.executemany(sql, abns) pg_cur.commit() finally: self._oracle_conn.close() self._postgres_conn.close()
Отредактировано dake (Апрель 13, 2017 09:37:22)
Офлайн
class Foo(object): def decorator(self, func): def wrapper(): func() return wrapper @decorator def foo(self): print "OK!" f = Foo() f.foo()
Traceback (most recent call last): File "/Users/asmirnov/PycharmProjects/test2/test.py", line 1, in <module> class Foo(object): File "/Users/asmirnov/PycharmProjects/test2/test.py", line 8, in Foo @decorator TypeError: decorator() takes exactly 2 arguments (1 given)
Офлайн
Посмотрите например здесь: https://github.com/django/django/blob/master/django/utils/decorators.py
Вам может помочь что-то типа декоратора method_decorator превращает декораторы функций в декораторы методов класса.
Офлайн
вам надо вынести их из классаа как мне вынести их из класса, если я там вызываю функцию из этого класса)
Офлайн
dakeВы плохо продумали архитектуру приложения и пытаетесь решить косяки своего решения путем внедрения костылей в саму сущность языка программирования. Просто подумайте хорошенько и решите задачу по-другому. Например, вы знаете, наверняка, что декоратор может принимать аргументы, значит вы в него можете передать что угодно, но не делайте его методом класса, это концептуально неправильно.
а как мне вынести их из класса, если я там вызываю функцию из этого класса)
Офлайн