публиковать строки CSV и удалять их после публикации

#python #api #csv #request

#python #API #csv #запрос

Вопрос:

У меня есть raspberry pi с термопарой, записывающей строки данных о температуре в два csv: локальный для pi и data_queue csv. Затем у меня есть другой скрипт, который запускается как отдельный процесс-демон, который должен использовать содержимое data_queue csv и отправлять post-запрос с каждой строкой в api. Чтобы избежать дубликатов, я хочу удалить каждую строку csv-файла очереди, которая публикуется в api. У меня есть следующий код:

 def post(root):
    headers = []
    sent = []                               # this will contain every line that is sent to the api
    
    with open(root '/data_queue.csv', 'r') as f:
        reader = csv.reader(f)
        request_headers = {'Content-Type': 'application/json'}
        headers = next(reader)                  # grab headers
        for line in reader:                     # loop over lines in csv
            payload = {}                        # make a payload dict with the headers as keys and the values as the line content
            sent.append(line)
            for i in range(len(headers)):       # fill the payload
                if i == 0 or i == 1 or i == 3:  # convert data to its appropriate type
                    line[i] = int(line[i])
                if i == 5 or i == 6 or i == 7:
                    try:
                        line[i] = float(line[i])
                    except ValueError as m:     # correction and uncertainty are filled as 'None' until we actually calibrate the thermos
                        logger.warning('{}: No data was found for {}'.format(m, headers[i]))
                        line[i] = 0
                        
                payload.update( {headers[i]: line[i]} )
                
            # convert the dict to json, and make a post request to the api
            response = requests.post('http://192.168.1.67:5000/new_row', headers=request_headers, data = json.dumps(payload))
            status = response.status_code
            logger.debug('{}: sent'.format(status) if status == 200 else '{}: failed to send'.format(status))
            
            if status == 500: # remove line from sent list if the line fails to post
                sent.pop(len(sent)-1)
    
    print(sent)
    logger.debug('starting clean')
    csv_cleanup(root, sent, headers)
    logger.debug('csv cleaned')
        
def csv_cleanup(root, sent, headers):        
    leftovers = []
    new = root '/data_queue_edit.csv'
    old = root '/data_queue.csv'
    
    with open(new, 'w') as out:      # create edit csv
        logger.error('made new csv')
        writer = csv.writer(out)
        writer.writerow(headers)
        logger.error('wrote headers')
        
    with open(old, 'r') as inp:      # open old csv and grab leftovers
        logger.error('opened old csv')
        reader = csv.reader(inp)
        next(reader)                 # skip headers
        for old_row in reader:
            leftovers.append(old_row)
            for new_row in sent:     # compare old csv and all sent rows, if dt's match up then remove it from leftovers
                
                if old_row[2] == new_row[2]:
                    leftovers.pop(leftovers.index(old_row))
                    logger.error('removed {}'.format(new_row))

    with open(new, 'a') as out:      # append leftovers to new csv
        logger.error('appending to new csv')
        writer = csv.writer(out)
        for row in leftovers:
            logger.error('writing {}'.format(row))
            writer.writerow(row)
            
    os.remove(old)
    os.rename(new, old)             # replace old csv with new csv
    logger.error('renamed file')
    
  

Хотя это работает, если есть ситуация, когда raspberry pi добавляет данные перемещения в очередь csv после их публикации, но до того, как они были очищены, тогда я потеряю указанные данные. Есть ли какая-либо работа вокруг этого, кроме синхронизации моих сценариев для синхронизации очереди, чтобы избежать потери данных?

Комментарии:

1. Почему бы вам не загрузить новый файл json / csv для каждой новой записи, а затем попросить приложение-потребителя удалить этот файл после его обработки? Таким образом, у вас не возникнет проблем с обоими приложениями, пытающимися заблокировать файл?

2. Просто попробовал это и заработало, я, похоже, не могу обнаружить никаких недостатков, из-за которых данные были бы потеряны. Большое спасибо за предложение!