2017-12-11 25 views
0

apscheduler에서 실행중인 작업에서 sqlite3에 값을 삽입하는 데 문제가 있습니다.APSCHEDULER를 사용하는 SQLite의 SQL INSERT

내가 찾고있는 것은 작업에서 값을 삽입하는 방법입니다. 호스트 스레드에서 작업을 실행한다는 의미일까요? 또는 버퍼를 채우고 SQL 트랜잭션을 관리하는 단일 스레드로 퍼널링합니까?

이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 나는 이것을 나중에 플라스크 (flask) 애플리케이션 내에서 실행시킬 계획이다.

""" 
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

커서가 필요한 함수 (및 스레드)에 연결하여 만듭니다. 바로 지금 당신은 하나의 글로벌 연결을 만들고 있습니다. – 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()