2017-08-06 24 views
1

私たちのDjango(== 1.11.4)環境でPyMySQL(== 0.7.11)を使用しようとしました。しかし、複数のアクションが同時に実行される場合(複数の要求が同じAPI関数に送信される)、問題が発生します。PyMySQL with Django、マルチスレッドアプリケーション

私たちは、このエラーを取得する:

pymysql.err.InternalError: Packet sequence number wrong - got 6 expected 1

我々はDB(大規模な要求は、複数のユーザーから来るいくつかの時間)からレコードを削除しようとしています。

コード:

def delete(self, delete_query): 
    self.try_reconnect() 
    return self._execute_query(delete_query) 

def try_reconnect(self): 
    if not self.is_connected: 
     self.connection.ping(reconnect=True) 

@property 
def is_connected(self) 
    try: 
     self.connection.ping(reconnect=False) 
     return True 
    execpt: 
     return False 

def _execute_query(self, query): 
    with self.connection.cursor() as cursor: 
     cursor.execute(query) 
     self.connection.commit() 
     last_row_id = cursor.lastrowid 
    return last_row_id 

私はデフ(自己)機能を接続で初期化 とself.connection、それらの機能がDBHandlerクラスの一部であることを指摘することは必要だと思いませんでした。

def connect(self): 
    self.connection = pymysql.connect(...) 

このconnect関数を実行するとDjangoの起動中に、我々はグローバルインスタンスプロジェクト全体のDBHandlerの(varaible)、および複数のファイルをインポートを作成します。

私たちはを削除クエリを実行するためのゲートウェイとして機能させるためにを使用しています。

何が間違っているのですか?そしてそれをどうやって修正することができますか?

+0

あなたは問題が何であるかは述べていません。なぜDjangoのormを使うのではなく、直接接続を使用していますか? –

+0

私たちは既に存在するDB(私たち以外)に書いています。 問題は、アクションを並行して実行しているときに例外が発生していることです。 例外のタイプ: 1. InternalError:パケットシーケンス番号が間違っています 2. AttributeError: 'NoneType'オブジェクトに 'timeout'属性がありません。 – SpazaM

答えて

1

は、問題を発見

PyMySQLは、私たちが行ったような接続を共有することnot thread saftyです(私たちはグローバルインスタンスとして複数のファイル間のクラスのインスタンスを共有 - クラスに一つだけの接続があります)、それを1として標識されます:PEP 249によると

threadsafety = 1

:PyMySQLのgithubの問題のコメントの

1 - Threads may share the module, but not connections.

ワン:

you need one pysql.connect() for each process/thread. As far as I know that's the only way to fix it. PyMySQL is not thread safe, so the same connection can't be used across multiple threads.

任意の方法あなたがスレッドのアプリケーションのためのMySQLdbと呼ばれる他のPythonパッケージを使用して考えた場合、MySQLdbはメッセージへの通知:

Don't share connections between threads. It's really not worth your effort or mine, and in the end, will probably hurt performance, since the MySQL server runs a separate thread for each connection. You can certainly do things like cache connections in a pool, and give those connections to one thread at a time. If you let two threads use a connection simultaneously, the MySQL client library will probably upchuck and die. You have been warned. For threaded applications, try using a connection pool. This can be done using the Pool module.

は、最終的には、DjangoのORMを使用するために管理し、我々はのためにだけ書いています具体的なテーブルは、inspectdbを使用して管理しています。