烧瓶-防止多个打开的mysql连接?

时间:2018-10-15 14:11:48

标签: python mysql flask

我创建了一个以mysql为后端的Flask应用程序。要启动数据库连接,我使用了以下内容:

@app.before_request
def db_connect():    
    try:
        g.db = MySQLdb.connect(host="localhost", user="root", passwd="", db="ddb",cursorclass=MySQLdb.cursors.DictCursor,autocommit=True)        
    except Exception as e:                
        print(e)

@app.teardown_request
def db_disconnect(exception=None):
    try:
        if g.db is not None:
            g.db.close()
    except Exception as e:
        print(e)

将此文件加载到init_py中。但是我检查了这个mysql打开和关闭了多少次,它很多。因为连接是打开和关闭的,所以即使css / js文件请求调用也是如此。我在所有函数中都调用g.db。 如何避免这种情况?

1 个答案:

答案 0 :(得分:1)

好问题。基本上,您提供的代码会在每个请求之前启动数据库连接。每个访问的url都是一个请求-包括检索到的图像或样式表-因此,这很常见。

该怎么办?

  • snippet可能会更有效,但仍会在每次请求时创建一个数据库。您可以检查出来。

  • 建议直接路由到您的静态变量。当肯定不需要数据库连接时,这将删除很多请求。有烧瓶本身可以执行此操作-请参见this post。我个人使用flask + WSGI,并在我的WSGIDaemonProcess文件中的行httpd.conf上方添加了这个小脚本。

    Alias "/static/" "/home/user/webapps/flask_app/flask_app/static/"
    <Directory "/home/user/webapps/flask_app/flask_app/static/">
          Require all granted
    </Directory>
    
  • 您的所有视图都需要数据库吗?否则,仅在所需的视图上获得连接。

    from functools import wraps
    from flask import g
    
    def make_db_connection(func): 
        """ decorate views that need a database connection """
        @wraps(func)
        def decorated_function(*args, **kwargs):
             if 'db' not in g:
                 g.db = connect_to_database()
             return func(*args, **kwargs)
         return decorated_function
    
    @app.teardown_appcontext
    def teardown_db():
        """ close if opened """
        db = g.pop('db', None)
        if db is not None:
            db.close()
    
  • 您可以在数据库周围制作一个小型class / API,并缓存最常见的请求。当然仅适用于select。参见此pretty project

    class Database():
    
         @threaded_cached_property_with_ttl(ttl=60*60)  # in seconds 
         def some_popular_query():
              connection = MySQLdb.connect(host="localhost", user="", passwd="", db="")
              return connection.get_query()
    

插图

为了说明,假设我们有一个带有template/main.html的简单网站。

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"</script>
    <script src="static/style/test.css"></script>
</head>
<body> 
    {{message}}
    <img src="static/img/test.png' />
</body>

还有index.py

 from flask import Flask
 app = Flask(__name__)

 @app.route('/')
 def hello_world():
     return render_template('index.html', message='Hello world')

使用您描述的flask网站,您将有一个请求页面和模板,另一个请求样式表,另一个请求图像。那是对您的数据库的3次调用!