Исправил импорт данных с привязкой спутников
This commit is contained in:
@@ -122,6 +122,72 @@ MINIMUM_BANDWIDTH_MHZ = 0.08
|
||||
|
||||
RANGE_DISTANCE = 56
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# Вспомогательные функции для работы со спутниками
|
||||
# ============================================================================
|
||||
|
||||
class SatelliteNotFoundError(Exception):
|
||||
"""Исключение, возникающее когда спутник не найден в базе данных."""
|
||||
pass
|
||||
|
||||
|
||||
def get_satellite_by_norad(norad_id: int) -> Satellite:
|
||||
"""
|
||||
Получает спутник по NORAD ID с обработкой ошибок.
|
||||
|
||||
Args:
|
||||
norad_id: NORAD ID спутника
|
||||
|
||||
Returns:
|
||||
Satellite: объект спутника
|
||||
|
||||
Raises:
|
||||
SatelliteNotFoundError: если спутник не найден
|
||||
ValueError: если norad_id некорректен
|
||||
"""
|
||||
if not norad_id or norad_id == -1:
|
||||
raise ValueError(f"Некорректный NORAD ID: {norad_id}")
|
||||
|
||||
try:
|
||||
return Satellite.objects.get(norad=norad_id)
|
||||
except Satellite.DoesNotExist:
|
||||
raise SatelliteNotFoundError(
|
||||
f"Спутник с NORAD ID {norad_id} не найден в базе данных. "
|
||||
f"Добавьте спутник в справочник перед импортом данных."
|
||||
)
|
||||
except Satellite.MultipleObjectsReturned:
|
||||
# Если по какой-то причине есть дубликаты, берем первый
|
||||
return Satellite.objects.filter(norad=norad_id).first()
|
||||
|
||||
|
||||
def get_satellite_by_name(name: str) -> Satellite:
|
||||
"""
|
||||
Получает спутник по имени с обработкой ошибок.
|
||||
|
||||
Args:
|
||||
name: имя спутника
|
||||
|
||||
Returns:
|
||||
Satellite: объект спутника
|
||||
|
||||
Raises:
|
||||
SatelliteNotFoundError: если спутник не найден
|
||||
"""
|
||||
if not name or name.strip() == "-":
|
||||
raise ValueError(f"Некорректное имя спутника: {name}")
|
||||
|
||||
try:
|
||||
return Satellite.objects.get(name=name.strip())
|
||||
except Satellite.DoesNotExist:
|
||||
raise SatelliteNotFoundError(
|
||||
f"Спутник '{name}' не найден в базе данных. "
|
||||
f"Добавьте спутник в справочник перед импортом данных."
|
||||
)
|
||||
except Satellite.MultipleObjectsReturned:
|
||||
# Если есть дубликаты по имени, берем первый
|
||||
return Satellite.objects.filter(name=name.strip()).first()
|
||||
|
||||
def get_all_constants():
|
||||
sats = [sat.name for sat in Satellite.objects.all()]
|
||||
standards = [sat.name for sat in Standard.objects.all()]
|
||||
@@ -307,7 +373,12 @@ def fill_data_from_df(df: pd.DataFrame, sat: Satellite, current_user=None, is_au
|
||||
is_automatic: если True, точки не добавляются к Source (optional, default=False)
|
||||
|
||||
Returns:
|
||||
int: количество созданных Source (или 0 если is_automatic=True)
|
||||
dict: словарь с результатами импорта {
|
||||
'new_sources': количество созданных Source,
|
||||
'added': количество добавленных точек,
|
||||
'skipped': количество пропущенных дубликатов,
|
||||
'errors': список ошибок
|
||||
}
|
||||
"""
|
||||
try:
|
||||
df.rename(columns={"Модуляция ": "Модуляция"}, inplace=True)
|
||||
@@ -321,6 +392,7 @@ def fill_data_from_df(df: pd.DataFrame, sat: Satellite, current_user=None, is_au
|
||||
new_sources_count = 0
|
||||
added_count = 0
|
||||
skipped_count = 0
|
||||
errors = []
|
||||
|
||||
# Словарь для кэширования Source в рамках текущего импорта
|
||||
# Ключ: (имя источника, id Source), Значение: объект Source
|
||||
@@ -391,13 +463,21 @@ def fill_data_from_df(df: pd.DataFrame, sat: Satellite, current_user=None, is_au
|
||||
added_count += 1
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Строка {idx + 2}: {str(e)}"
|
||||
print(f"Ошибка при обработке строки {idx}: {e}")
|
||||
errors.append(error_msg)
|
||||
continue
|
||||
|
||||
print(f"Импорт завершен: создано {new_sources_count} новых источников, "
|
||||
f"добавлено {added_count} точек, пропущено {skipped_count} дубликатов")
|
||||
f"добавлено {added_count} точек, пропущено {skipped_count} дубликатов, "
|
||||
f"ошибок: {len(errors)}")
|
||||
|
||||
return new_sources_count
|
||||
return {
|
||||
'new_sources': new_sources_count,
|
||||
'added': added_count,
|
||||
'skipped': skipped_count,
|
||||
'errors': errors
|
||||
}
|
||||
|
||||
|
||||
def _create_objitem_from_row(row, sat, source, user_to_use, consts, is_automatic=False):
|
||||
@@ -574,6 +654,11 @@ def _create_objitem_from_row(row, sat, source, user_to_use, consts, is_automatic
|
||||
|
||||
|
||||
def add_satellite_list():
|
||||
"""
|
||||
Добавляет список спутников в базу данных (если их еще нет).
|
||||
|
||||
Примечание: Эта функция устарела. Используйте админ-панель для добавления спутников.
|
||||
"""
|
||||
sats = [
|
||||
"AZERSPACE 2",
|
||||
"Amos 4",
|
||||
@@ -673,7 +758,12 @@ def get_points_from_csv(file_content, current_user=None, is_automatic=False):
|
||||
is_automatic: если True, точки не добавляются к Source (optional, default=False)
|
||||
|
||||
Returns:
|
||||
int: количество созданных Source (или 0 если is_automatic=True)
|
||||
dict: словарь с результатами импорта {
|
||||
'new_sources': количество созданных Source,
|
||||
'added': количество добавленных точек,
|
||||
'skipped': количество пропущенных дубликатов,
|
||||
'errors': список ошибок
|
||||
}
|
||||
"""
|
||||
df = pd.read_csv(
|
||||
io.StringIO(file_content),
|
||||
@@ -711,6 +801,7 @@ def get_points_from_csv(file_content, current_user=None, is_automatic=False):
|
||||
new_sources_count = 0
|
||||
added_count = 0
|
||||
skipped_count = 0
|
||||
errors = []
|
||||
|
||||
# Словарь для кэширования Source в рамках текущего импорта
|
||||
# Ключ: (имя источника, имя спутника, id Source), Значение: объект Source
|
||||
@@ -733,14 +824,15 @@ def get_points_from_csv(file_content, current_user=None, is_automatic=False):
|
||||
skipped_count += 1
|
||||
continue
|
||||
|
||||
# Получаем или создаем объект спутника
|
||||
# sat_obj, _ = Satellite.objects.get_or_create(
|
||||
# name=sat_name, defaults={"norad": row["norad_id"]}
|
||||
# )
|
||||
# Получаем объект спутника по NORAD ID
|
||||
try:
|
||||
sat_obj = get_satellite_by_norad(row["norad_id"])
|
||||
except (SatelliteNotFoundError, ValueError) as e:
|
||||
error_msg = f"Строка {idx + 2}: {str(e)}"
|
||||
print(error_msg)
|
||||
errors.append(error_msg)
|
||||
continue
|
||||
|
||||
sat_obj, _ = Satellite.objects.get_or_create(
|
||||
norad=row["norad_id"], defaults={"name": sat_name}
|
||||
)
|
||||
source = None
|
||||
|
||||
# Если is_automatic=False, работаем с Source
|
||||
@@ -785,13 +877,21 @@ def get_points_from_csv(file_content, current_user=None, is_automatic=False):
|
||||
added_count += 1
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Строка {idx + 2}: {str(e)}"
|
||||
print(f"Ошибка при обработке строки {idx}: {e}")
|
||||
errors.append(error_msg)
|
||||
continue
|
||||
|
||||
print(f"Импорт завершен: создано {new_sources_count} новых источников, "
|
||||
f"добавлено {added_count} точек, пропущено {skipped_count} дубликатов")
|
||||
f"добавлено {added_count} точек, пропущено {skipped_count} дубликатов, "
|
||||
f"ошибок: {len(errors)}")
|
||||
|
||||
return new_sources_count
|
||||
return {
|
||||
'new_sources': new_sources_count,
|
||||
'added': added_count,
|
||||
'skipped': skipped_count,
|
||||
'errors': errors
|
||||
}
|
||||
|
||||
|
||||
def _is_duplicate_by_coords_and_time(coord_tuple, timestamp, tolerance_km=0.001):
|
||||
@@ -923,9 +1023,12 @@ def _create_objitem_from_csv_row(row, source, user_to_use, is_automatic=False):
|
||||
pol = "-"
|
||||
|
||||
pol_obj, _ = Polarization.objects.get_or_create(name=pol)
|
||||
sat_obj, _ = Satellite.objects.get_or_create(
|
||||
name=row["sat"], defaults={"norad": row["norad_id"]}
|
||||
)
|
||||
|
||||
# Получаем объект спутника по NORAD ID
|
||||
try:
|
||||
sat_obj = get_satellite_by_norad(row["norad_id"])
|
||||
except (SatelliteNotFoundError, ValueError) as e:
|
||||
raise Exception(f"Не удалось получить спутник: {str(e)}")
|
||||
|
||||
# Ищем данные в TechAnalyze
|
||||
tech_data = _find_tech_analyze_data(row["obj"], sat_obj)
|
||||
|
||||
Reference in New Issue
Block a user