我在这个主题上经历了多个问题,我仍然感到困惑。我正在努力寻找在多个Python模块之间共享数据库连接的最佳方式。我也看过Borg模式,但是当我们需要共享数据库连接时,它看不出它是如何有用的。
这就是我所拥有的: 我正在使用Redis作为我的数据库,并希望在多个模块之间共享redis连接。
选项1:正如下面Jared所建议的,我可以创建一个redis连接并将其传递到任何地方。
class Crawler:
def __init__(self, url_store):
self._url_store = url_store
class UrlStore:
def __init__(self, redis_client):
self._redis_client = redis_client
if __name__ == '__main__':
redis_client = redis.StrictRedis(host='localhost',
port=6379,
db=0,
decode_responses=True)
url_store = UrlStore(redis_client)
c = Crawler(url_store)
选项2:将redis连接包装在一个类中。
class RedisConnection:
client = redis.StrictRedis(host='localhost',
port=6379,
db=0,
decode_responses=True)
class Crawler:
def __init__(self, url_store):
self._url_store = url_store
class UrlStore:
def __init__(self):
self._redis_client = RedisConnection.client
if __name__ == '__main__':
url_store = UrlStore()
c = Crawler(url_store)
使用选项1,不需要担心单例等,但我认为我们在各处泄露数据库信息。
选项2感觉不太优雅。
我认为这里有一个更大的设计问题..应该在需要的地方“注入”数据库连接......还是应该根据需要从全局/单例/共享状态访问它?
答案 0 :(得分:0)
只是一个想法,创建一个数据库实例池。说三/五。 并有一个dbPool字典
dbPool = {client _inst1 = 0, client _inst2 = 0, client _inst3 = 0}
键 - > db instance,value - > 0/1(0-dbconn free,1 dbconn inuse)
每当你需要一个实例时,有一个小线程安全fn:
def getThreadSafeConnection(self) :
for dbConn, value in self.dbPool.items() :
if value == 0 :
self.lock() # lock
self.dbPool[dbConn] = 1 # db cursor in use
self.unlock()
return dbConn
return createNewConn() // if no dbConn is free
执行查询后重置dbInstance Flag
self.lock()
self.dbPool[dbConn] = 0 # db cursor is free
self.unlock()
这将确保正确的查询执行。如果您觉得可能发生更多db命中,那么请增加dbPool大小。