я предоставлю тебе часть кода, ответственного за загрузку данных в базу. Действие происходит очень медленно. Проанализируй код и предоставь варианты увеличения скорости добавления данных. Если необходимы дополнительные данные - спрашивай.
Код:
я предоставлю тебе часть кода, ответственного за загрузку данных в базу. Действие происходит очень медленно. Проанализируй код и предоставь варианты увеличения скорости добавления данных. Если необходимы дополнительные данные - спрашивай.
Код:
def parse_csv_for_os(filepath: str):
    """
    Функция для загрузки/обновления таблицы OS из CSV с использованием SQLAlchemy.
    """
    logger.debug(f"[DEBUG] parse_csv_for_os: Начинаем обработку файла {filepath}")
    # -------------------------------------------------
    # 1. Считываем весь файл как «сырые» строки
    # -------------------------------------------------
    try:
        with open(filepath, "r", encoding="cp1251") as f:
            lines = f.readlines()
    except UnicodeDecodeError:
        logger.error(f"[ERROR] Не удалось прочитать файл в кодировке cp1251. Попробуйте другую.")
        return
    except FileNotFoundError:
        logger.error(f"[ERROR] Файл не найден: {filepath}")
        return
    # -------------------------------------------------
    # 2. Удаляем  первые строки
    # -------------------------------------------------
    if len(lines) <= 2:
        logger.warning("[WARN] Файл содержит <= 1 строк, после удаления нечего обрабатывать.")
        return
    lines = lines[1:]
    # -------------------------------------------------
    # 3. Удаляем строки по regexp
    # -------------------------------------------------
    cleaned_lines = []
    pattern = re.compile(r"^\s*\d+\s*$")  # если строка содержит только число
    for line in lines:
        if pattern.match(line.strip()):
            continue
        cleaned_lines.append(line)
    cleaned_text = "".join(cleaned_lines)
    # -------------------------------------------------
    # 4. Чтение CSV через pandas
    # -------------------------------------------------
    csv_data = StringIO(cleaned_text)
    field_name = 'name', 'inv', 'passport_number', 'reg_number', 'zn', 'nn', \
        'date_warranty', 'date_production', 'date_expluatation', 'date_input', \
        'date_output', 'date_trash', 'quantity', 'model', 'made_by', \
        'code_party', 'period', 'dop_inv', 'record_number', 'filial_number', \
        'description', 'groups', 'type_doc', 'ed_izm', 'group_os', \
        'vid_os', 'podrazdelenie', 'mol', 'code_norma_amort', 'norma_amort', \
        'uses_os', 'price', 'summ_amort', 'amort_otch_period', 'price_input', \
        'iznos_input', 'fix_summ_amort', 'srok_polezn_use', 'valute', \
        'metod_nach_amort', 'tho_amort', 'type_object', 'code_group_okof', \
        'name_group_okof', 'popravka_koef', 'last_price'
    try:
        df = pd.read_csv(csv_data, header=None, names=field_name ,sep=";", dtype=str)
    except Exception as e:
        logger.error(f"[ERROR] Ошибка при чтении CSV (pandas): {e}")
        return
    # -------------------------------------------------
    # 5. Сопоставление столбцов DataFrame с полями модели OS
    # -------------------------------------------------
    required_columns = [column.name for column in OS.__table__.columns]
    # Проверим наличие нужных столбцов в df
    missing_cols = [c for c in required_columns if c not in df.columns]
    if missing_cols:
        logger.warning(f"[WARN] В CSV отсутствуют столбцы: {missing_cols}. Обработка может быть неполной.")
    # -------------------------------------------------
    # 6. Обработка строк и сохранение в базе данных
    # -------------------------------------------------
    updated_count = 0
    inserted_count = 0
    for _, row in df.iterrows():
        inv = str(row.get("inv") or "").strip()
        if not inv:
            continue
        # Поиск существующей записи
        existing_os = OS.query.filter_by(inv=inv).first()
        # Создание словаря с параметрами
        params = {}
        for col in required_columns:
            val = row.get(col, None)
            # Конвертация данных при необходимости
            if col in ("date_warranty", "date_production", "date_expluatation",
                    "date_input", "date_output", "date_trash"):
                val = parse_date(val)
            elif col in ("price", "last_price"):
                val = parse_float(val)
            elif col == "quantity":
                val = parse_int(val)
            else:
                if val is None or pd.isna(val):
                    val = None
                else:
                    val = str(val).strip()
            params[col] = val
        # Обновление или создание записи
        if existing_os:
            for key, value in params.items():
                if key == "os_id":
                    logger.warning(f"[WARN] Поле os_id не должно обновляться, пропускаем.")
                    continue
                setattr(existing_os, key, value)
            try:
                db.session.commit()
                updated_count += 1
            except Exception as e:
                db.session.rollback()
                logger.warning(f"[WARN] Ошибка при обновлении OS (inv={inv}): {e}")
                logger.debug(f"[DEBUG] Данные, вызвавшие ошибку: {params}")
            logger.debug(f"[DEBUG] OS ID: {existing_os.os_id}, inv: {existing_os.inv}")
        else:
            new_os = OS(**params)
            db.session.add(new_os)
            try:
                db.session.commit()
                inserted_count += 1
            except Exception as e:
                db.session.rollback()
                logger.warning(f"[WARN] Ошибка при вставке OS (inv={inv}): {e}")
    logger.debug(f"[DEBUG] parse_csv_for_os: Обработка завершена. Обновлено: {updated_count}, добавлено: {inserted_count}")