я получаю эту ошибку FileNotFoundError: [Errno 2] Нет такого файла или каталога
когда я пытаюсь записать файл csv в корзину, используя средство записи csv, которое перебирает пакеты данных. Полное понимание журналов Cloud Function вокруг этой ошибки:
Файл "/workspace/main.py", строка 299, в файле write_to_csv_file с
открыть (путь к файлу, "w") как outcsv: FileNotFoundError: [Errno 2] Нет такого
файл или каталог: 'gs://MY_BUCKET/MY_CSV.csv'
Выполнение функции заняло 52655 мс, завершено со статусом: «сбой».
ПРЕДУПРЕЖДЕНИЕ OpenBLAS - не удалось определить размер кэша L2 на этом
система, предполагая 256k ```
И это несмотря на то, что этот bucket_filepath определенно существует: я могу загрузить пустой фиктивный файл и получить его «URI gsutils» (щелчок правой кнопкой мыши по трем точкам в правой части файла), и Bucket_filepath будет выглядеть так же: 'gs://MY_BUCKET/MY_CSV.csv'
.
Вместо этого я проверил сохранение фиктивного кадра данных pandas, используя pd.to_csv
и это работало с тем же ведром_filepath (!).
Следовательно, должна быть другая причина, вероятно, писатель не принят, или с заявлением
который открывает файл.
Код, который выдает ошибку, выглядит следующим образом. Тот же код работает за пределами Google Cloud Function в обычном задании cron на локальном сервере. Я добавил два отладочных отпечатка вокруг строки, которая выдает ошибку, print("Сразу после открытия файла...")
больше не появляется. Подфункция query_execute_batch()
что write_to_csv_file()
вызывается для каждого пакета, но, скорее всего, это не проблема, так как ошибка возникает уже в самом начале при открытии файла csv для записи.
требования.txt
(которые затем импортируются как модули):
SQLAlchemy>=1.4.2
облачное хранилище Google> = 1.16.1
mysqlclient == 2.1.0
панды == 1.2.3
fsspec==2021.11.1
gcsfs == 2021.11.1
юникодексв == 0.14.1
И из main.py
:
def query_execute_batch (соединение):
"""Функция чтения данных из результата запроса в пакеты
:yield: каждый результат в цикле представляет собой пакет результатов запроса
"""
результаты = execute_select_batch (соединение, SQL_QUERY)
print(f"len(результаты): {len(результаты)}")
для результата в результатах:
дать результат
def write_to_csv_file (соединение, путь к файлу):
"""Запишите данные в цикле по пакетам в csv.
Это делается партиями, так как запрос из базы данных огромен.
:param connection: подключение mysqldb к БД
:param filepath: путь к CSV-файлу для записи данных
возвращает: метаданные по строкам и времени
"""
счетчики = 0
print("Прямо перед открытием файла...")
с open(filepath, "w") как outcsv:
print("Сразу после открытия файла...")
писатель = csv.DictWriter(
аутксв,
имена полей=ИМЯ ПОЛЯ,
дополнительное действие = "игнорировать",
разделитель="|",
линиятерминатор="\n",
)
# записать заголовок в соответствии с именами полей
писатель.writeheader()
для партии в query_execute_batch (соединение):
писатель.writerows (пакет)
счетчики += длина (пакет)
datetime_now_save = datetime.now()
вернуть счетчики, datetime_now_save
Имейте в виду, что для работы приведенного выше сценария я импортирую gcsfs
что делает ведро доступным для чтения-записи-записи. В противном случае мне, вероятно, понадобится объект облачного хранилища Google, например:
storage_client = хранилище.Клиент()
ведро = storage_client.bucket(BUCKET_NAME)
а затем создайте файл в этом ведре с дополнительными функциями, но здесь это не цель.
В дальнейшем pd.to_csv
код, который работает, он использует вывод фиктивного SQL-запроса ВЫБЕРИТЕ 1
в качестве ввода кадра данных. Этот может быть сохранены в тот же Bucket_filepath, конечно, причина может быть не только в pd.to_csv()
как таковой, но также и то, что набор данных является фиктивным, а не сложными строками Юникода из огромного ВЫБЕРИТЕ запрос
. Или есть другая причина, я только предполагаю.
если записи не None:
df = pd.DataFrame(records.fetchall())
df.columns = записи.ключи()
df.to_csv (путь к файлу,
индекс=ложь,
)
datetime_now_save = datetime.now()
счетчики = df.shape[0]
Я хотел бы использовать модуль записи csv, чтобы иметь возможность писать в юникоде с помощью модуля unicodecsv и использовать пакеты.
Я мог бы захотеть перейти на партии (цикл + добавление
режим или размер куска
) в пандах, как в Запись больших кадров данных Pandas в файл CSV по частям чтобы избавиться от этой проблемы с путем к файлу ведра, но я бы предпочел использовать готовый код (никогда не трогайте работающую систему).
Как я могу сохранить этот CSV с помощью средства записи CSV, чтобы он мог открыть новый файл в ведре в записывать
режим = с open(filepath, "w") как outcsv:
?
Данная функция write_to_csv_file()
— это лишь крошечная часть облачной функции, которая использует широкий спектр функций и каскадных функций. Я не могу показать здесь весь воспроизводимый случай и надеюсь, что на него можно будет ответить с помощью опыта или более простых примеров.