Вопрос или проблема
Я импортирую данные из csv файла в базу данных с помощью API. Я уже запустил скрипт ниже, и чуть меньше половины данных было импортировано. Что-то заставило API остановиться, и теперь я ищу возможность запустить скрипт снова. Я протестировал несколько строк из csv файла, и данные, которые уже были импортированы, дублируются. Есть ли способ изменить скрипт так, чтобы импортированные данные пропускались? Я думал о каком-то условном операторе, но не совсем уверен. Какие предложения?
def opencsv():
'''Эта функция открывает csv файл'''
input_csv = 'agentlinks.csv'
file = open(input_csv, 'r')
csvin = csv.reader(file)
#Пропустить строку заголовка
next(csvin, None)
return csvin
def addUriLink():
"""Добавить URI ссылку в запись."""
api_url, headers = as_login.login()
csvfile = opencsv()
for row in csvfile:
repo_id = row[1]
resource_id = row[2]
value = row[3]
resource_uri='repositories/' + repo_id + '/resources/' + str(resource_id)
resource_json = requests.get(api_url + '/repositories/' + repo_id + '/resources/' + str(resource_id), headers=headers).json()
updatedRecord = resource_json
agents = updatedRecord['linked_agents']
agent = {}
agent['ref'] = value
agent['role'] = 'subject'
if agent not in agents:
agents.append(agent)
updatedRecord['linked_agents'] = agents
print(updatedRecord['linked_agents'])
updatedRecord = json.dumps(updatedRecord)
print(api_url + resource_uri)
post = requests.post(api_url + '/repositories/' + repo_id + '/resources/' + str(resource_id), headers=headers, data=updatedRecord).json()
print(post)
else:
print('нет обновлений')
log = open("addAgentsLinks.txt", "a")
print(updatepost, file=log)
addUriLink()
Ответ или решение
Вопрос импорта данных из CSV-файла и предотвращения дублирования уже загруженных данных является актуальным и требует взвешенного подхода. Ваша задача состоит в том, чтобы изменить существующий код так, чтобы он пропускал записи, которые уже были импортированы в базу данных через API. Ниже приведен подробный план, как это можно реализовать.
1. Определение уникальности записи
Первый шаг заключается в том, чтобы определить, как вы будете идентифицировать уникальные записи. В вашем случае, это может быть комбинация repo_id
и resource_id
, так как они однозначно идентифицируют ресурс в вашей системе.
2. Создание списка уже импортированных записей
Вам нужно создать коллекцию (например, множество), в которой будут храниться идентификаторы уже загруженных записей. Один из способов сделать это – сохранить их в отдельный файл или базу данных, или загружать их в память при запуске скрипта.
3. Модификация функции addUriLink
Добавьте логику проверки перед добавлением нового агента. Вот переработанный пример вашего скрипта с учетом предложенных изменений:
import csv
import requests
import json
def opencsv():
'''Эта функция открывает CSV файл'''
input_csv = 'agentlinks.csv'
with open(input_csv, 'r', newline='', encoding='utf-8') as file:
csv_reader = csv.reader(file)
# Пропустить строку заголовка
next(csv_reader, None)
return csv_reader
def fetch_imported_ids():
'''Получение идентификаторов уже импортированных записей'''
imported_ids = set()
try:
with open("imported_ids.txt", 'r') as f:
for line in f:
imported_ids.add(line.strip())
except FileNotFoundError:
pass # Если файл не найден, возвращаем пустое множество
return imported_ids
def addUriLink():
"""Добавляет URI ссылку к записи."""
api_url, headers = as_login.login()
csvfile = opencsv()
imported_ids = fetch_imported_ids()
for row in csvfile:
repo_id = row[1]
resource_id = row[2]
value = row[3]
id_key = f"{repo_id}-{resource_id}"
# Пропускать записи, которые уже были импортированы
if id_key in imported_ids:
print(f"Запись {id_key} уже импортирована, пропускаем.")
continue
resource_uri = 'repositories/' + repo_id + '/resources/' + str(resource_id)
resource_json = requests.get(api_url + '/repositories/' + repo_id + '/resources/' + str(resource_id), headers=headers).json()
updated_record = resource_json
agents = updated_record.get('linked_agents', [])
agent = {'ref': value, 'role': 'subject'}
if agent not in agents:
agents.append(agent)
updated_record['linked_agents'] = agents
updated_record_json = json.dumps(updated_record)
print(api_url + resource_uri)
post = requests.post(api_url + '/repositories/' + repo_id + '/resources/' + str(resource_id), headers=headers, data=updated_record_json).json()
print(post)
# Сохранение идентификатора уже импортированной записи
with open("imported_ids.txt", 'a') as f:
f.write(f"{id_key}\n")
else:
print('Нет обновления')
log = open("addAgentsLinks.txt", "a")
print(post, file=log)
addUriLink()
Объяснение изменений:
-
Функция
fetch_imported_ids
: Загрузка идентификаторов уже импортированных записей из файла. Если файла не существует, просто продолжаем с пустым множеством. -
Проверка уникальности: Перед тем, как обработать любую запись из CSV, скрипт проверяет, была ли она уже импортирована, путем создания строкового ключа на основе
repo_id
иresource_id
. -
Сохранение идентификаторов: После успешного добавления нового агента, идентификатор записи записывается в файл
imported_ids.txt
.
Заключение
С помощью предложенных изменений вы сможете избежать повторного импорта данных, используя простой и эффективный метод. Это не только поможет сохранить целостность данных, но и сократит время выполнения вашего скрипта при повторных запусках.