Как начать писать оболочку Python вокруг другой оболочки? - PullRequest
1 голос
/ 08 января 2012

Я знаю, что этот вопрос задавали один или два человека, но это как-то отличается от того, что я имею в виду.Пожалуйста, потерпите меня.

Я пытаюсь написать оболочку для существующей оболочки couchdb-python.Причина этого в том, что в случае, если в будущем мы решим переключиться на другую базу данных NoSQL, например MongoDB, мне придется изменить только одну часть моей кодовой базы.

Вопрос 1. Является ли предложенный правильный курс действий с учетом приведенного выше сценария?

Проблема с доступом к couchdb с использованием оболочки couchdb-python, иногда (не всегда), имени пользователя/ пароль необходим для доступа к базе данных.Вот как это выглядит в коде:

server = Server()   <---- When no username/password is required
server = Server('http://abc:123@localhost:5984')  <---- When username/password is required

Как бы я определил начальную init функцию для обслуживания обоих сценариев.У меня сейчас что-то вроде этого:

from couchdb import Server


class Couch(object):
    """ CouchDB Wrapper """
    COUCHDB_URI = {username_not_provided: 'http://localhost:5984',
                   username_provided: 'http://%s:%s@localhost:5984'}
    def __init__(self, username=None, password=None):
        if username and password:
            self.url = COUCHDB_URI['username_provided'] % (username, password)
        else:
            self.url = COUCHDB_URI['username_not_provided']
        self.server = Server(self.url)

Я думаю, что код выглядит некрасиво, кто-то может указать мне правильное направление для вышеизложенного?

Спасибо всем!Я действительно ценю помощь.

Ответы [ 2 ]

2 голосов
/ 08 января 2012

Это построение ответа larsmans на ваш конкретный вопрос о форматировании, но я думаю, что вы могли бы пойти по-другому, чем этот. Возможно, было бы лучше сначала создать базовый класс, который определяет общий интерфейс для любого из ваших бэкэндов NoSQL. Примерно так:

class Database(object):

    def __init__(self, **kwargs):
        self.connect(**kwargs)

    def connect(self, **kwargs):
        pass


class Couch(Database):

    def __init__(**kwargs):
        super(Couch, self).__init__(**kwargs)

    def connect(self, username=None, password=None):
        if username and password:
            # connect this way
            pass
        else:
            # connect that way
            pass

Класс базы данных будет определять все методы интерфейса, которые должны реализовывать подклассы. Таким образом, ваш код более высокого уровня может принимать общий объект базы данных, и вам просто нужно будет определить новые модули для разных бэкэндов NoSQL.

Редактировать

Вам стоит взглянуть на нереля Джанго: http://www.allbuttonspressed.com/projects/django-nonrel

Они выполняют ту же задачу для django, используя mongodb в качестве основного выбора, но вы сможете добавить больше поддержки, реализовав несколько их базовых классов для CouchDB. Это должно дать вам хорошее представление о том, как они этого добиваются, поскольку django - это та же идея, использующая не зависящий от уровня слой ORM над сменными базами данных базы данных.

1 голос
/ 08 января 2012

Вы можете сделать это так:

class Couch(object):
    URI_TEMPLATE = "http://%slocalhost:5984"

    def __init__(self, username=None, password=None):
        if username and password:
            user_part = "%s:%s@" % (username, password)
        else:
            user_part = ""
        self.url = URI_TEMPLATE % user_part

хотя недостатком здесь является то, что %s не выделяется в шаблоне URI.

Боюсь, это не станет намного красивее, чем это.

...