2015-12-09 6 views
7

PyMySQLに依存するApacheで実行されているFlaskアプリケーションがあります。アプリケーションは、一連のRESTコマンドを提供します。それは全体のソースを設けることなく、Pythonの3Flask/ApacheのPyMySQLが空の結果を返すことがある

の下で実行され、プログラムが構成されています

#!flask/bin/python 
import json 
import pymysql 
from flask import * 

# Used to hopefully share the connection if the process isn't restarted 
mysql_connection = None 

# Gets the mysql_connection, or opens it 
GetStoreCnx(): 
    global mysql_connection 
    if (mysql_connection != None): 
     store_connection_string = "" 
     # Get the connection string from the config file 
     with open('config/storedb.json', 'r') as f: 
      store_connection_string = json.load(f) 
     mysql_connection = pymysql.connect(**store_connection_string) 
    return mysql_connection; 


class Server(Flask): 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 

# Return results via REST 
@app.route('/results1', methods=['GET']) 
def get_result1(): 
    cnx = GetStoreCnx(); 
    cursor = cnx.cursor(); 
    query = """ 
     SELECT 
      result_name, 
      successful 
     FROM 
      results 
     """ 
    cursor.execute(query) 
    cnx.commit() 
    result = cursor.fetchall() 
    return json.dumps(result) 

# Run server, if needed 
if __name__ == '__main__': 
    app.run(host='0.0.0.0', debug=True) 

がありますが、いくつかのより多くのREST呼び出し - しかし、彼らはすべて本質的に同じことを行う(すなわち - 取得カーソルを作成し、基本的なselectクエリを実行します.2つ以上のフィールドがあり、クエリを実行し、結果をフェッチしてJSONオブジェクトとして返します)。コミットは不必要であるはずですが、古いデータを取得するPyMySQLの実行中の問題と思われます。

これらのREST呼び出しが空のJSONセット(つまり、[])を返すことがあるという問題があります。さらに調査したところ、完全に空の結果が返されますが、例外はスローされませんでした。これは定期的に発生しますが、すべてではありません。一部の呼び出しは、値を正常に返します。私が行くの呼び出しを維持しようとすると、それは(として:

while(cursor.execute(query) < 1): 
    pass 

)の結果を返すまでのプロセスは、最終的には(すぐに)、それ以上の要求をサービスするからApacheを防ぐ、無限ループに入ります。

サーバは(現在のところ)1秒あたり約5通しかサービスしていません。開発サーバーを使用してもこの問題は発生しません。

このエラーを防止する方法はありますか? PyMySQLの障害ですか? MySQLに正しく接続できないことがありますか?

1 Threads may share the module, but not connections. 

フラスコ内conncurrent要求が異なるによって提供されるように:あなたは、あなたのアプリケーションで使用されている一つのグローバルmysqlの接続を作成している

答えて

1

、hoveverのpymysqlはdbapi2 specification手段に従って1のthreadsafetyを宣言しますあなたは接続を共有すべきではありません。開発用サーバーを使用する際に問題が発生しない理由は、シングルスレッドで実行されるためです。さらに用flask.gに保管し、要求ごとに新しい接続を作成

  • さらなる使用のためにローカルスレッドとしてそれを保存し、スレッドごとに新しい接続を作成

    • :あなたはどちらかでしこれを避けるために

      import threading 
      thread_local = threading.local() 
      
      def GetStoreCnx():   
          if not hasattr(thread_local, 'mysql_connection'): 
           store_connection_string = "" 
           # Get the connection string from the config file 
           with open('config/storedb.json', 'r') as f: 
            store_connection_string = json.load(f) 
           mysql_connection = pymysql.connect(**store_connection_string) 
           thread_local.mysql_connection = mysql_connection 
          return thread_local.mysql_connection; 
      
      :あなたのGetStoreCnx機能は次のように変更することができそうするために

    を使用

    SQLAlchemyは、scoped_session()と同様の処理を行います。これはまた、thread_localの代わりにflask.gで動作し、要求ごとに1つの接続を行う必要があります。

  • 関連する問題