2026, Jan 05 03:01

Как загрузить файлы Feather в PostgreSQL с помощью pandas

Как без ручного DDL загрузить файлы Feather в PostgreSQL: pandas DataFrame.to_sql создаёт таблицы и сразу вставляет данные. Простой и надёжный конвейер.

Когда у вас каталог, набитый файлами Feather с десятками столбцов и сотнями тысяч строк, вручную писать CREATE TABLE для каждого файла — долго и легко ошибиться. Цель очевидна: сгенерировать таблицы и загрузить данные, не прописывая снова и снова каждый столбец и его тип.

Как выглядит первоначальный подход

Ниже — компактный пример, который перебирает папку, читает каждый .feather в DataFrame, сопоставляет типы PostgreSQL с dtypes pandas и собирает оператор CREATE TABLE. Это отражает привычное стремление сгенерировать DDL программно, а потом придумать, как массово загрузить данные.

import os
import glob
import pandas as pd
base_dir = "E:\\file_path"
feather_items = glob.glob(os.path.join(base_dir, '*.feather'))
for asset_path in feather_items:
    print(f"File: {asset_path}")
    frame = pd.read_feather(asset_path)
    rel_name = {asset_path}
    type_map = frame.dtypes.to_dict()
    sql_parts = []
    def pd_kind_to_pg(kind):
        if pd.api.types.is_integer_dtype(kind):
            return "INTEGER"
        elif pd.api.types.is_float_dtype(kind):
            return "FLOAT"
        elif pd.api.types.is_bool_dtype(kind):
            return "BOOLEAN"
        elif pd.api.types.is_datetime64_any_dtype(kind):
            return "TIMESTAMP"
        else:
            return "TEXT"
    for col_name, kind in type_map.items():
        pg_kind = pd_kind_to_pg(kind)
        sql_parts.append(f'"{col_name}" {pg_kind}')
    ddl_stmt = f"CREATE TABLE {rel_name} (  {' '.join(sql_parts)} );"

Почему это становится препятствием

Даже с успешно сгенерированным DDL всё упирается в надёжный способ загрузить строки в базу с той же схемой. Вставлять по столбцам — значит быстро получить громоздкую процедуру вставки. На этом многие конвейеры и буксуют: определение таблицы есть, а массовой загрузки — нет.

Простой путь: поручите pandas создать таблицу и загрузить данные

В pandas есть встроенный метод для сохранения DataFrame в SQL‑базе. На практике это избавляет от самописного DDL и отдельной логики вставки для каждого файла. Один вызов: DataFrame задаёт схему и сразу же загружает данные.

from sqlalchemy import create_engine
import pandas as pd
import os
import glob
root_dir = "E:\\file_path"
feathers = glob.glob(os.path.join(root_dir, '*.feather'))
for asset in feathers:
    print(f"File: {asset}")
    frame = pd.read_feather(asset)
    dest_name = asset
    engine_obj = create_engine("postgresql+psycopg2://user:pass@localhost/database")
    frame.to_sql(name=dest_name, con=engine_obj)

Здесь используется подключение к базе через SQLAlchemy, а каждый DataFrame записывается прямо в таблицу. Имя таблицы берётся из пути к файлу — в соответствии с предложенным подходом.

Почему это важно

Замена ручной генерации DDL и вставок «на коленке» одним вызовом упрощает поддержку и уменьшает риск несоответствий схемы. Когда вы обрабатываете множество файлов с большим числом столбцов, отказ от кастомного SQL — практичное преимущество: процесс от обнаружения файлов до загрузки данных остаётся единообразным.

Итоги

Если вы уже читаете Feather через pandas, используйте DataFrame.to_sql для одновременного создания схемы и вставки данных. По сравнению с ручными CREATE TABLE и отдельной логикой вставки для каждого файла это экономит время и держит конвейер сосредоточенным на данных, а не на шаблонном SQL.