Flask - предотвратить несколько открытых подключений mysql? - PullRequest
0 голосов
/ 15 октября 2018

Я создал приложение фляги с MySQL в качестве бэкэнда.Чтобы установить соединение с БД, я использовал следующее:

@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 голосов
/ 15 октября 2018

Хороший вопрос.По сути, предоставленный вами код запускает соединение БД перед каждым запросом.Каждый посещенный URL-адрес является одним запросом, включая полученные изображения или таблицы стилей, так что это довольно часто.

Что делать?

  • Этот фрагмент может быть немного более эффективным, но все равно создаст базу данных накаждый запрос.Вы можете проверить это.

  • Рекомендуется направить прямо к вашей статике.Это удалит много запросов, когда соединение с базой данных точно не требуется.Есть несколько вариантов сделать это с самой колбой - см. этот пост .Я лично использую 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 конечно.Посмотрите на этот красивый проект .

    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')

На сайте колбы, который вы описываете, у вас будет один запрос на страницу и шаблон, другой запрос на таблицу стилей иеще один для изображений.Это 3 звонка в вашу базу данных!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...