如何开始围绕另一个包装器编写python包装器?

时间:2012-01-08 18:42:48

标签: python couchdb wrapper

我知道这个问题已被一两个人提出过,但它与我的想法有所不同。请耐心等待。

我正在尝试围绕现有的couchdb-python包装器编写一个包装器。这样做的原因是,如果我们决定将来切换到另一个NoSQL数据库,例如MongoDB,我只需要更改代码库的一部分。

问题1:鉴于上述情况,这是建议的正确行动吗?

使用couchdb-python包装器访问couchdb的问题,有时(并非所有时间),用户名/密码是访问数据库所必需的。这就是代码中的样子:

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 个答案:

答案 0 :(得分:2)

这是基于larsmans对你的特定格式问题的回答,但我认为你可能想要以不同的方式去做。最好先创建一个Base类,为任何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后端定义新模块。

修改

你应该看看nonrel django:http://www.allbuttonspressed.com/projects/django-nonrel

他们正在为django完成同样的任务,使用mongodb作为他们的主要选择,但是你可以通过为CouchDB实现一些基类来增加更多的支持。这应该让你很好地了解它们是如何实现的,因为django是一个相同的想法,使用不可知的ORM层而不是可交换的数据库后端。

答案 1 :(得分:1)

你可以这样做:

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模板中不突出。

我恐怕不会比这更漂亮。