flask 中使用连接池和 app_context 求助

2015-10-20 14:03:45 +08:00
 bg7lgb
v2ex 的处女贴,奉献给 flask 。

刚开始学 flask ,还没时间看 sqlalchemy 。

python2.7 , flask 0.10.1 。数据库是 oracle ,使用了 cx_Oracle 作为驱动。

按以往的经验,在创建了一个连接池,每次有请求进行时从池子中获取获取一个 connection ,访问 db 后,把 connection release 回池中。

问题:
1 、看打出来的日志,只初始化了一次连接池,结果出来两次“ connect db ”。
2 、对于 app_context 的使用还是很困惑。
何时需要 app_context , app_context 是否是唯一的?
如何把池的信息附加到 app_context ,使在每次的 request 时都可以正确获取到。

附件 1 : db.py
import cx_Oracle as cxo
from flask import current_app

try:
from flask import _app_ctx_stack as stack
except ImportError:
from flask import _request_ctx_stack as stack

class OraDB(object):
def __init__(self, app=None):
self.app = app
if app is not None:
self.init_app(app)


def init_app(self, app):
if hasattr(app, 'teardown_appcontext'):
app.teardown_appcontext(self.teardown)
else:
app.teardown_request(self.teardown)

print 'connect db'
ctx = app.app_context()
ctx.push()

self.pool = cxo.SessionPool(user=current_app.config['DBUSER'], \
password=current_app.config['DBPASSWORD'], \
dsn=current_app.config['DSN'], \
min=current_app.config['MIN'], \
max=current_app.config['MAX'], \
increment=current_app.config['INCREMENT'], threaded=True)

def connect(self):
conn = self.pool.acquire()
print 'in connect: pool id:', id(self.pool), ' conn id:', id(conn)
return conn

def teardown(self, exception):
ctx = stack.top
if hasattr(ctx, 'oradb'):
print "teardown " + str(id(ctx.oradb))
self.pool.release(ctx.oradb)

@property
def connection(self):
ctx = stack.top
if ctx is not None:
if not hasattr(ctx, 'oradb'):
ctx.oradb = self.connect()
return ctx.oradb

附件 2 : app.py
from flask import Flask, current_app
from db import OraDB

app = Flask(__name__)
app.config.from_pyfile('config.cfg')

db = OraDB(app)

@app.route('/')
def index():
cur = db.connection.cursor()
cur.execute("select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual")
rs = cur.fetchall()
return rs[0][0]

if __name__ == "__main__":
app.run(debug=True)
5779 次点击
所在节点    Python
2 条回复
bg7lgb
2015-10-20 14:12:33 +08:00
实际上数据库连接也是出现了两个,也就是产生了两个连接池。
连接池的参数 : min 1 max 5 increment 1

netstat -an|findstr "1521"
TCP 192.1.4.78:5983 10.9.5.167:1521 ESTABLISHED
TCP 192.1.4.78:6006 10.9.5.167:1521 ESTABLISHED
tftk
2015-11-01 01:46:28 +08:00
1. 把 DB Pool 放到 flask._app_ctx_stack 里,这样全局 能共享一个连接池。
2. 需要的时候创建一个连接放到 flask.g 里,并在 teardown_request 里关闭这个连接。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/229516

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX