Как массово изменить именование фотографий товаров (opencart, mysql)?
В магазине есть много-много товаров, у них может быть одна или несколько картинок. Именуются картинки моделями товаров. Основная картинка товара хранится в SQL в таблице oc_product (там же модель, штрихкод и т.д.), дополнительные (при наличии) в oc_product_image (каждая картинка новой записью), сквозной id товара у этих таблиц - product_id.
Проблема, что от разных товаров могут быть картинки с одинаковым именем (поэтому пришлось раскладывать по папкам).
Нужно перейти на новую систему: именуем все картинки по штрихкоду товара (чтобы картинки уж точно стали уникальными), дополнительные картинки так же переименовываем в <штрихкод>_1.jpg и т.д.
То есть, две задачи: массовое переименование и массовое изменение ссылок на картинке в базе.
Как это лучше выполнить? Я у мамы программист, настраивал микроволновку и пхп.
В принципе, могу выгрузить все товары в CSV с форматом: "ID товара";"штрихкод";"полный путь к картинке"
Основная картинка товара хранится в SQL в таблице oc_product (там же модель, штрихкод и т.д.), дополнительные (при наличии) в oc_product_image (каждая картинка новой записью), сквозной id товара у этих таблиц - product_id.
Это плохо. денормализация. Лучше ВСЕ картинки класть в oc_product_image, а в таблице oc_product хранить ссылку на ту самую "основную" картинку.
именуем все картинки по штрихкоду товара (чтобы картинки уж точно стали уникальными), дополнительные картинки так же переименовываем в <штрихкод>_1.jpg и т.д.
Будет лучше, если ВСЕ имена будут соответствовать единому шаблону. Так что основная картинка должна быть, например, <штрихкод>_0.jpg
Всё это может упростить дальнейшую работу со значениями.
Да, предложенный мной псевдокод можно адаптировать для использования с MySQL. Однако, в MySQL нет встроенной поддержки циклов для работы с каждой записью из выборки напрямую в SQL-запросе. Вам придется использовать язык программирования для обработки каждой записи или написать хранимую процедуру в MySQL. Вот примерный алгоритм, который можно реализовать, например, на Python:
Подключиться к базе данных MySQL с помощью Python (используя библиотеку pymysql или mysql-connector-python).
Выполнить SQL-запрос для получения product_id и barcode из таблицы oc_product.
Для каждой полученной записи:
Обновить поле image в oc_product, используя barcode.
Выполнить запрос к oc_product_image для получения всех дополнительных изображений для этого product_id.
Обновить каждое изображение в oc_product_image, добавив к barcode суффикс в виде порядкового номера.
Вот примерный код на Python:
import pymysql
# Параметры подключения к базе данных
conn = pymysql.connect(host='your_host', user='your_user', password='your_password', db='your_db')
try:
with conn.cursor() as cursor:
# Получаем все продукты
cursor.execute("SELECT product_id, barcode FROM oc_product WHERE barcode IS NOT NULL")
products = cursor.fetchall()
for product_id, barcode in products:
# Обновляем основное изображение
cursor.execute("UPDATE oc_product SET image = %s WHERE product_id = %s", (barcode + '.jpg', product_id))
# Получаем дополнительные изображения для каждого продукта
cursor.execute("SELECT image_id FROM oc_product_image WHERE product_id = %s", (product_id,))
images = cursor.fetchall()
for i, img in enumerate(images, start=1):
# Обновляем каждое дополнительное изображение
cursor.execute("UPDATE oc_product_image SET image = %s WHERE image_id = %s", (f"{barcode}_{i}.jpg", img['image_id']))
conn.commit()
finally:
conn.close()
Этот код сначала обновит основные изображения товаров в oc_product, а затем перейдет к обновлению дополнительных изображений в oc_product_image. Убедитесь, что у вас есть правильные разрешения и что вы создали резервную копию вашей базы данных перед запуском такого скрипта.
Valentin Barbolin, если это и правда ответ от ChatGPT - то что ещё от него ждать...
На самом деле, имея доступ к штрихкоду и старому имени файла, несложно в MySQL построить текст команды переименования и сохранить сразу все команды переименования в текстовый файл скрипта. После чего останется просто запустить этот файл на исполнение в шелле операционки.