ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

共享txpostgres连接池

2019-10-29 03:55:20  阅读:235  来源: 互联网

标签:postgresql twisted psycopg2 python


我们有一个RESTful(-ish)扭曲的应用程序,它使用txpostgres访问postgres数据库.当前,每当客户端ping服务器进行数据库调用时,我们都会生成新的txpostgres.Connection实例.这效率低下,导致我们的数据库很快变得不堪重负.我一直试图将其改编为使用txpostgres.ConnectionPool,但是遇到了麻烦.现在,我有这样的东西:

class DBTester(object):
    def __init__(self):
        self.cfg = load_config('local')  # load the db settings from a JSON file
        self.pool = ConnectionPool(None, min=1, **self.cfg) # create the pool

    @defer.inlineCallbacks
    def get_pool(self):
        yield self.pool.start()
        defer.returnValue(self.pool)


class DBT(object):
    def __init__(self):
        self.db = DBTester()

    @defer.inlineCallbacks
    def t(self):
        conn = yield self.db.get_pool()
        res = yield conn.runQuery('select * from clients')
        println('DBT.t result: {}'.format(res))


if __name__ == "__main__":
    dbt = DBT()
    dbt.t()
    dbt.t()

    reactor.run()

问题是pool.start()调用的时间安排.如果将其放在DBTester .__ init__中,则会得到psycopg2.OperationalError:正在进行异步连接尝试.如果我将其放在DBTester.get_pool中,则一个db.t()调用会起作用,而另一个会失败,并带有exception.AttributeError:’NoneType’对象没有属性’runQuery’.我基本上整天都在为此而苦苦挣扎,还无法破解,也无法在网上找到很多东西.

我真的只需要一个指向如何使用ConnectionPool的最小示例的指针.有什么建议么?

解决方法:

听起来您的问题不在于txpostgres,而在于扭曲和异步的思维方式.

exceptions.AttributeError:’NoneType’对象没有属性’runQuery’的意思是:
您试图在建立连接之前在数据库之后引发SQL查询.真傻!因此,现在我想我将抛出一个异常,以便亲爱的用户知道这种疯狂.

因此,如果您有类似

pool = ConnectionPool(None, min=1)
d1 = pool.start()
d2 = pool.runQuery('select tablename from pg_tables')

此代码在反应堆中创建了两个deferd和thorws em.只有调度算法才知道首先执行两个算法中的哪一个,如果是d2,则会发生错误.

txpostgres.txpostgres.AlreadyConnected表示:
很好的自我解释,启动已经启动的池没有任何意义.

psycopg2.OperationalError:正在进行异步连接尝试意味着:
当您开始执行SQL语句时,我正在建立一个不错的异步数据库连接.数据库连接尚未准备好,因此未执行sql查询,这让我很难过.我想我会抛出操作错误,因此亲爱的用户知道该语句失败.

好的,因此我们需要一种方法来确保在建立SQL查询到数据库之后才建立连接.下面是一个使用回调实现此目的的代码示例.

from txpostgres.txpostgres import ConnectionPool
from twisted.internet import reactor, defer
from twisted.python import log, util


class SomeClass(object):

    pool = ConnectionPool(
        None,
        min=1,
        user="user",
        password="pass",
        host='host.com')

    @defer.inlineCallbacks
    def fetch_tables(self):
        res = yield self.pool.runQuery('select tablename from pg_tables')
        defer.returnValue(res)


if __name__ == "__main__":

    def querydb(n=10):
        dl = []
        for i in range(n):
            d = s.fetch_tables()
            d.addCallback(lambda tables: util.println(len(tables)))
            dl.append(d)
        return defer.DeferredList(dl)

    s = SomeClass()
    d_startpool = s.pool.start()
    d_startpool.addCallback(lambda _: querydb())
    d_startpool.addCallback(lambda _: s.pool.close())
    d_startpool.addErrback(log.err)
    d_startpool.addBoth(lambda _: reactor.stop())

    reactor.run()

希望这可以帮助.

标签:postgresql,twisted,psycopg2,python
来源: https://codeday.me/bug/20191029/1957339.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有