2017-08-14 15 views
0

私はdjangoでWebサーバーを構築しました。Django:データベースに新しく接続する方法

タスクを実行するスレッドを使用して、クライアントからデータベースに送信されたデータを保存します。

while True: 
     ... 
     try: 
      self.dbTarget, created = ClientMonitor.objects.get_or_create(Machine_code=own_MachC) 

      data = self.workQueue.get() #from client sent 

      self.dbTarget.setValue(data) #Custom method assigning 
      self.dbTarget.save()   #django ORM 
     except InterfaceError as ee: 
      pass 

スレッドが長時間実行されるが、それは8時間のタイムアウトとしてMySQLサーバの切断ので、久しぶりにInterfaceErrorを除く外になります。

Especially it can not auto-reconnect to the db. Creating a new thread will be OK, but it will increase resource occupation.

だから私は接続が同じスレッドに閉じたときにDBを再接続します。また、Djangoはそれぞれのリクエストに新しい接続を取得します。

同じスレッドでデータベースに新しく接続する方法は? ありがとうございました!

+0

私は 'InterfaceError 'をシミュレートするために' connection.connection.close() 'を呼び出すことができますが、これは異なるかもしれません。 – Mix

答えて

0

例外ハンドラで接続を閉じるだけです。新しい接続は、アプリケーションがデータベースと通信しようとする次の時間を確立する必要があります:

import logging 
from django.db import connection 

try: 
    self.dbTarget, created = ClientMonitor.objects.get_or_create(Machine_code=own_MachC) 
    ... 
except InterfaceError as ee: 
    logging.warning(ee) # make sure that you log these events 
    connection.close() 
+0

私は 'connection.connection.close()'を呼び出して 'InterfaceError'をシミュレートすると、 'connection.close()'が接続を再現します。 – Mix

+0

素晴らしい!それは働く。 mysql-serverのwait_timeoutを8時間から3秒に変更します。そして、私の編集のように再接続します。 – Mix

0

ジャンゴ自体は、すべてのリクエストの開始時と終了時にその生涯過去のすべての接続を閉じるように機能close_old_connections()を使用しています。これにより、接続がデータベース設定で指定されたMAX_AGEより古いかどうかが検出されます。そうでない場合は使用できません。 MAX_AGEをデータベースのタイムアウトよりも低く設定すると、dbタイムアウトのためにInterfaceErrorが発生することはありません。

from django.db import close_old_connections 

while True: 
    try: 
     ... 
    finally: 
     close_old_connections() 
+0

私はCONN_MAX_AGEパラメタを設定しないので、デフォルト値は0です。 'close_old_connections()'がOKかどうかは、InterfaceErrorを除いて8時間かかったのでテストできません。 – Mix

+0

'InterfaceError'をシミュレートするために 'connection.connection.close()'を呼び出し、 'django.db.utils.ProgrammingError:クローズされた接続を閉じる'以外は 'close_old_connections()'となります。 – Mix

+0

@ミックスもちろん、サーバー側でタイムアウトした接続は、クライアント側から明示的にクローズされた接続と同じではなく、異なるエラーが発生します。サーバーのタイムアウトは 'close_old_connections()'で処理する必要があります。 – knbk

関連する問題