2017-12-11 28 views
0

apschedulerで実行中のジョブからsqlite3に値を挿入する際に問題が発生しました。APSCHEDULERを使用したSQLiteのSQL INSERT

私が探しているのは、ジョブの値を挿入する方法です。これは、ホストスレッドからジョブを実行することを意味すると思いますか?または、バッファを充填し、SQLトランザクションを管理する単一のスレッドにそれを振り向ける?

これを処理する最善の方法は何ですか?私は後でフラスコのアプリ内でこれを実行する予定です。ここで

はコードです:

""" 
Demonstrates how to use the background scheduler to schedule a job that executes on 3 second 
intervals. 
""" 

from datetime import datetime 
import time 
import os 

from apscheduler.schedulers.background import BackgroundScheduler 


def tick(): 
    print('Tick! The time is: %s' % datetime.now()) 

def tick1(): 
    print('Tick1! The time is: %s' % datetime.now()) 
    id = "testId" 
    global sql_cursor 
    sql_cursor.execute("INSERT INTO histories VALUES(?,?,?)", (datetime.now(),id,0.0)) 


if __name__ == '__main__': 
    import sqlite3 
    sql_db = sqlite3.connect('histories.db') 
    sql_cursor = sql_db.cursor() 
    sql_cursor.execute(
    '''CREATE TABLE IF NOT EXISTS histories(
     timestamp DATE, id TEXT, value REAL)''') 
    sql_db.commit() 

    scheduler = BackgroundScheduler() 
    scheduler.add_job(tick, 'interval', seconds=3) 
    scheduler.start() 
    scheduler.add_job(tick1, 'interval', seconds=1) 
    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C')) 

    try: 
     # This is here to simulate application activity (which keeps the main thread alive). 
     while True: 
      time.sleep(2) 
    except (KeyboardInterrupt, SystemExit): 
     # Not strictly necessary if daemonic mode is enabled but should be done if possible 
     scheduler.shutdown() 

とエラー:

Tick1! The time is: 2017-12-11 22:22:59.232296 
    Job "tick1 (trigger: interval[0:00:01], next run at: 2017-12-11 22:22:59 UTC)" raised an exception 
    Traceback (most recent call last): 
     File "/usr/local/lib/python3.5/dist-packages/apscheduler/executors/base.py", line 125, in run_job 
     retval = job.func(*job.args, **job.kwargs) 
     File "background.py", line 20, in tick1 
     sql_cursor.execute("INSERT INTO histories VALUES(?,?,?)", (datetime.now(),id,0.0)) 
    sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread.The object was created in thread id -1225585456 and this is thread id -1260391312 
+1

なぜ別のスレッドで作成されたカーソルオブジェクトを使用していますか?本当に必要な場所(= tick1)に接続を作成しようとしましたか?もちろん、同じ場所でコミットしてください。 – dgan

+0

カーソルが必要な機能(とスレッド)に接続して作成してください。今はただ1つのグローバル接続を作成していますが、これはうまくありません。 – davidism

+0

これは今試してみます。接続してカーソルをすばやく作成するのは問題ですか? – candronikos

答えて

0

接続とカーソルが簡単にスレッド間で使用することはできません。また、コメントの中であなたの質問に答えるために、使用終了時にconnection.close()を実行する限り、接続をすばやく連続して作成する上で問題はありません。 以下の例では、どのように見えるかを知ることができます。接続して実行する独自のクラスを作成することで、それを整理することができます。

import os 
from apscheduler.schedulers.background import BackgroundScheduler 
def tick(): 
    print('Tick! The time is: %s' % datetime.now()) 

def tick1(): 
    print('Tick1! The time is: %s' % datetime.now()) 
    id = "testId" 
    sql_db = sqlite3.connect('histories.db') 
    sql_cursor = sql_db.cursor() 
    sql_cursor.execute("INSERT INTO histories VALUES(?,?,?)", (datetime.now(),id,0.0)) 
    sql_cursor.close() 
    sql_db.close() 


if __name__ == '__main__': 
    import sqlite3 
    sql_db = sqlite3.connect('histories.db') 
    sql_cursor = sql_db.cursor() 
    sql_cursor.execute(
    '''CREATE TABLE IF NOT EXISTS histories(
     timestamp DATE, id TEXT, value REAL)''') 
    sql_db.commit() 
    sql_cursor.close() 
    sql_db.close() 
    scheduler = BackgroundScheduler() 
    scheduler.add_job(tick, 'interval', seconds=3) 
    scheduler.start() 
    scheduler.add_job(tick1, 'interval', seconds=1) 
    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C')) 

    try: 
     # This is here to simulate application activity (which keeps the main thread alive). 
     while True: 
      time.sleep(2) 
    except (KeyboardInterrupt, SystemExit): 
     # Not strictly necessary if daemonic mode is enabled but should be done if possible 
     scheduler.shutdown() 
関連する問題