Данные в таблицу заносятся дважды

Есть такой код, который берет данные с api и заносит их в бд. Если оставить как сейчас, то записанные данные в бд дублируются(при одном вызове функции run_schedule_reg). Когда удаляю все что связанно со вторым поток , данные не дублируются. Никак не пойму в чем тут проблема. В первом потоке я записываю данные в бд. Во втором их достаю из б.д.

import requests, time, datetime, json, schedule, sqlite3
from threading import Thread

conn = sqlite3.connect('parser.sqlite', check_same_thread = False)
url = 'http://127.0.0.1:8000/api/reg/'


def get_registers(date):
    full_page = requests.get(url, auth=("admin","admin"))
    pars=json.loads(full_page.content.decode('utf-8'))
    a=sorted(pars, key=lambda pars: pars['time_visit'])
    cursor = conn.cursor()
    with conn:
        cursor.execute("CREATE TABLE IF NOT EXISTS `register` (`time` STRING, `number_car` VARCHAR)")
        for i in a:
            if i['date_visit']==date:
                number_car=i["number_car"]
                time_visit=i["time_visit"]
                cursor.execute("insert into register values (?, ?)", (time_visit, number_car))
        conn.commit()
    cursor.close()

def run_schedule_reg():         
    now = datetime.datetime.now()
    date = now.strftime("%d-%m-%Y")
    schedule.every(1).minutes.do(get_registers,date)

    while True:
        schedule.run_pending()
        time.sleep(1)


def print_time_visit(time_now): 
    cursor = conn.cursor()
    with conn:
        cursor.execute("SELECT * FROM `register`")
        rows = cursor.fetchall()
        for row in rows:
            index=2
            time_db=row[0][:index] + row[0][index+1:]
            time_now_to_int =time_now[:index] + time_now[:index]
            if abs(int(time_db) - int(time_now_to_int) ) < 30:
                print(row[0], row[1])
    cursor.close()  

def run_schedule_time():            
    now = datetime.datetime.now()
    time_now = now.strftime("%H:%M")
    schedule.every(5).minutes.do(print_time_visit,time_now)

    while True:
        schedule.run_pending()
        time.sleep(1)


thread1 = Thread(target=run_schedule_reg).start()
thread2 = Thread(target=run_schedule_time).start()

Ответы (1 шт):

Автор решения: eri

У вас два треда выполняют задачи из одной очереди. Скорее всего при schedule.run_pending() задачи копируются и второй тред успевает их увидеть до того как первый снимит их с очереди

Второй тред убери, а таймер добавь в первый

Вот эта часть должна быть только один раз

while True:
    schedule.run_pending()
    time.sleep(1)

Сам код в таком виде.

import requests, time, datetime, json, schedule, sqlite3
from threading import Thread

conn = sqlite3.connect('parser.sqlite', check_same_thread = False)
url = 'http://127.0.0.1:8000/api/reg/'


def get_registers(date):
    full_page = requests.get(url, auth=("admin","admin"))
    pars=json.loads(full_page.content.decode('utf-8'))
    a=sorted(pars, key=lambda pars: pars['time_visit'])
    cursor = conn.cursor()
    with conn:
        cursor.execute("CREATE TABLE IF NOT EXISTS `register` (`time` STRING, `number_car` VARCHAR)")
        for i in a:
            if i['date_visit']==date:
                number_car=i["number_car"]
                time_visit=i["time_visit"]
                cursor.execute("insert into register values (?, ?)", (time_visit, number_car))
        conn.commit()
    cursor.close()

def run_schedule_reg():
    now = datetime.datetime.now()
    time_now = now.strftime("%H:%M")
    schedule.every(5).minutes.do(print_time_visit,time_now) # перенесем сюда

    now = datetime.datetime.now()
    date = now.strftime("%d-%m-%Y")
    schedule.every(1).minutes.do(get_registers,date)

    while True:
        schedule.run_pending()
        time.sleep(1)


def print_time_visit(time_now): 
    cursor = conn.cursor()
    with conn:
        cursor.execute("SELECT * FROM `register`")
        rows = cursor.fetchall()
        for row in rows:
            index=2
            time_db=row[0][:index] + row[0][index+1:]
            time_now_to_int =time_now[:index] + time_now[:index]
            if abs(int(time_db) - int(time_now_to_int) ) < 30:
                print(row[0], row[1])
    cursor.close()  

thread1 = Thread(target=run_schedule_reg).start()
# убрать thread2 = Thread(target=run_schedule_time).start()

Ещё тут момент time_now = now.strftime("%H:%M") нужно перенести в функцию если нужно время исполнения

→ Ссылка