Найти - Пользователи
Полная версия: Django - подключение к внешней базе данных по задаче.
Начало » Python для экспертов » Django - подключение к внешней базе данных по задаче.
1
VadimK
Есть проект на Djnago + UWSGI, который так же используется в качестве задач (аналог celery).
python 3 , в качестве драйвера к базе данных - mysqlclient

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

tasks.py , который осуществляет вызов
 from project.redmine.agregator import Redmine
@task(executor=TaskExecutor.SPOOLER, retry_count=1, retry_timeout=5)
def redmine_data_update():
    r = Redmine()
    r.import_tasks()

agregator.py , собственно как все происходит
 import logging
log = logging.getLogger('tasks')
class Redmine:
    db = None
    def __init__(self):
        self.db = _mysql.connect(host=settings.REDMINE_DB_HOST, db=settings.REDMINE_DB_NAME,
                                 user=settings.REDMINE_DB_USER, passwd=settings.REDMINE_DB_PASS)
        self.db.query("SET NAMES utf8;")
        self.db.query("SET CHARACTER SET utf8;")
        self.db.query("SET character_set_connection=utf8;")
        log.info('MySQL connection to redmine opened.')
    def __del__(self):
        self.db.close()
        log.info('MySQL connection to redmine closed.')
    def import_tasks(self):
        query = "SELECT ... сам запрос"
        try:
            self.db.query(query)
            res = self.db.use_result()
            rs = list(RedmineTasks.objects.filter().values_list('task_id', flat=True))
        except Exception as e:
            log.error('MySQL error: %s' % e)
            return
        row = res.fetch_row()

Проблема в том, что через пару часов перестает работать по причине “MySQL server has gone away”.
Т.е. изначально в логе вижу корректное
 (tasks:24) MySQL connection to redmine opened.
(tasks:28) MySQL connection to redmine closed.
На внешнем сервере соединения закрываются и хвостов нет. А через какое то время уже:
 (tasks:24) MySQL connection to redmine opened.
(tasks:48) MySQL error: (2006, 'MySQL server has gone away')
и на сервере куча не закрытых коннекшенов.

Собственно несколько вопросов:
1. почему при екзепшене и выходе из функции не срабатывает __del__ метод
2. как красиво решить задачу без принудительного вызова метода закрытия коннекшена


PooH
Сделайте открытие/закрытие соединения в блоке try … finally … вместо __init__/__del__, это вам не c++.
И, кстати, django же умеет соединения к разным базам из коробки, зачем так грубо - настройки подключения в коде.
FishHook
VadimK

use using() method, Luke!
VadimK
PooH
Сделайте открытие/закрытие соединения в блоке try … finally … вместо __init__/__del__, это вам не c++.
И, кстати, django же умеет соединения к разным базам из коробки, зачем так грубо - настройки подключения в коде.
Там просто несколько разных методов в классе, которые вытягивают разные данные. Хотелось бы в конструкторе открыть соединение, а в деструкторе закрыть.
Но __del__ почему то не всегда вызывается.

А по поводу соединения - просто в данном случае удобнее. Так как нигде более та база не используется и нет смысла ее в проект тащить.
PooH
VadimK
Там просто несколько разных методов в классе, которые вытягивают разные данные. Хотелось бы в конструкторе открыть соединение, а в деструкторе закрыть.
Ну поместите вызовы этих методов в один try .. finally или сделайте класс менеджером контекста в __enter__ откройте в __exit__ закройте.
VadimK
Но __del__ почему то не всегда вызывается.
Потому что на объект могут быть ссылки. Еще раз говорю - это не c++, __del__ может быть вызван когда счетчик ссылок на объект обнуляется, а если ссылки циклические (один объект на другой, а другой на первый), то когда сборщик мусора придет. А если процесс завершится раньше чем счетчики обнулятся, то может вообще не вызваться. Честно говоря, не скажу как тут соединение к базе будет закрыто, как бы не по таймауту.
VadimK
А по поводу соединения - просто в данном случае удобнее. Так как нигде более та база не используется и нет смысла ее в проект тащить.
Я и вижу насколько удобнее, вместо готового пула пилите велосипед(гарна штука лисопед, попа едет, ноги нет). И настройки вместо конфига расползаются по коду.

PS: насчет настроек не прав, уже после глянул первое сообщение с кодом и увидел что они из конфига
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