我知道这个问题已被一两个人提出过,但它与我的想法有所不同。请耐心等待。
我正在尝试围绕现有的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)
我认为代码看起来很难看,有人能指出我正确的方向吗?
谢谢大家!我非常感谢你的帮助。
答案 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模板中不突出。
我恐怕不会比这更漂亮。