Приложениям часто необходимо подключаться к другим службам (база данных, кэш, API и т. Д.). Для здравомыслия и DRY мы хотели бы сохранить все эти соединения в одном модуле, чтобы остальная часть нашей базы кода могла совместно использовать соединения.Управление созданием соединения в Python?
Для уменьшения шаблонного, использование вниз должно быть простым:
# app/do_stuff.py
from .connections import AwesomeDB
db = AwesomeDB()
def get_stuff():
return db.get('stuff')
и настройки соединения также должны быть простыми:
# app/cli.py or some other main entry point
from .connections import AwesomeDB
db = AwesomeDB()
db.init(username='stuff admin') # Or os.environ['DB_USER']
веб-рамки, как Django и колба сделать что-то вроде этого, но он чувствует себя немного неуклюжим:
Connect to a Database in Flask, Which Approach is better? http://flask.pocoo.org/docs/0.10/tutorial/dbcon/
Одна из серьезных проблем заключается в том, что мы хотим ссылаться на фактический объект соединения вместо прокси-сервера, потому что мы хотим сохранить завершение табуляции в среде iPython и других dev.
Так что же это за правильный путь (tm)? После нескольких итераций, вот моя идея:
#app/connections.py
from awesome_database import AwesomeDB as RealAwesomeDB
from horrible_database import HorribleDB as RealHorribleDB
class ConnectionMixin(object):
__connection = None
def __new__(cls):
cls.__connection = cls.__connection or object.__new__(cls)
return cls.__connection
def __init__(self, real=False, **kwargs):
if real:
super().__init__(**kwargs)
def init(self, **kwargs):
kwargs['real'] = True
self.__init__(**kwargs)
class AwesomeDB(ConnectionMixin, RealAwesomeDB):
pass
class HorribleDB(ConnectionMixin, RealHorribleDB):
pass
Номер для улучшения: Установка начальной __connection к родовому ConnectionProxy вместо None, который улавливает все доступы атрибута и генерирует исключение.
Я проделал здесь много шума и в различных проектах OSS и не видел ничего подобного. Он чувствует себя довольно солидно, хотя это означает, что куча модулей будет создавать объекты соединения в качестве побочного эффекта во время импорта. Это взорвется мне в лицо? Есть ли другие негативные последствия для этого подхода?
Спасибо за подробный ответ! Я действительно не считал безопасность ниток и вилок, я обязательно подумаю об этом. Re: ошибка соединения параметров, хорошая уловка и хорошее исправление. Re: пулы клиентов, также хорошая точка, но даже с пулом соединений вы хотите централизовать инициализацию и гарантировать, что вы используете один и тот же пул во всем приложении. – knite
Re: простая вспомогательная функция, я рассматривал этот подход изначально. Это быстро становится раздражающим из-за того, что каждый модуль должен импортировать awesome_db * и * вызывать его. – knite