Вставить в бд blob файл

  • Автор темы Автор темы Wide
  • Дата начала Дата начала

Wide

Client
Регистрация
04.02.2013
Сообщения
970
Реакции
262
Баллы
63
Парни, помогите пж составить запрос для вставки изображений в бд. Такой запрос
SQL:
Развернуть Свернуть Копировать
INSERT INTO `blob` (`value`) VALUES (LOAD_FILE('C:\1.jpeg'));
ничего не вставляет. Secure_file_priv на весь диск задан. Размер файла тоже в пределах конфига. Mysql 8.0.30.
 
сейчас вообще не вариант менять коней) данных на сотни гигабайт
знаем видали, был продакшн и довольно нагруженный, когда я понял что было бы ахеренно в соседнюю табличку тупо файлами писать. Переехал за 3 дня. И я офигел как 200 гб бд в муське, привратились в 60 гб на постгре
 
  • Спасибо
Реакции: Wide
Пробовал с басе64, разница в размерах не устраивает.Screenshot_306.png
 
знаем видали, был продакшн и довольно нагруженный, когда я понял что было бы ахеренно в соседнюю табличку тупо файлами писать. Переехал за 3 дня. И я офигел как 200 гб бд в муське, привратились в 60 гб на постгре
Буду пробовать ставить рядом с майскуэлем.
 
Парни, помогите пж составить запрос для вставки изображений в бд. Такой запрос
SQL:
Развернуть Свернуть Копировать
INSERT INTO `blob` (`value`) VALUES (LOAD_FILE('C:\1.jpeg'));
ничего не вставляет. Secure_file_priv на весь диск задан. Размер файла тоже в пределах конфига. Mysql 8.0.30.
Вот, такой код должен сработать, перепроверил, у меня сработал.
C#:
Развернуть Свернуть Копировать
// таблица была в таком виде:
// CREATE TABLE `mytable` (`blobdata` blob ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
string[] db_setting = new[] {
  string.Format("database={0}", db),
  string.Format(@"server={0}",ip),
  //string.Format(@"port={0}", "82"),
  string.Format(@"user id={0}", user),
  string.Format(@"password={0}", password)
};

string connect_db = string.Join("; ", db_setting);

var file = File.ReadAllBytes(@"C:\Users\User\Desktop\text primer.xmlz");
var val = new System.Collections.Specialized.OrderedDictionary {{"file", file}};
string SQL = @"INSERT INTO `testzenno`.`mytable` (`blobdata`) VALUES (@file);";
return ZennoPoster.Db.ExecuteNonQuery(SQL, val, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,connect_db);
96978
 
  • Спасибо
Реакции: ZX и Wide
Вот, такой код должен сработать, перепроверил, у меня сработал.
C#:
Развернуть Свернуть Копировать
// таблица была в таком виде:
// CREATE TABLE `mytable` (`blobdata` blob ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
string[] db_setting = new[] {
  string.Format("database={0}", db),
  string.Format(@"server={0}",ip),
  //string.Format(@"port={0}", "82"),
  string.Format(@"user id={0}", user),
  string.Format(@"password={0}", password)
};

string connect_db = string.Join("; ", db_setting);

var file = File.ReadAllBytes(@"C:\Users\User\Desktop\text primer.xmlz");
var val = new System.Collections.Specialized.OrderedDictionary {{"file", file}};
string SQL = @"INSERT INTO `testzenno`.`mytable` (`blobdata`) VALUES (@file);";
return ZennoPoster.Db.ExecuteNonQuery(SQL, val, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,connect_db);
Посмотреть вложение 96978
Большое человеческое спасибо. Еще не проверял но думаю то что нужно. Восстанови кворк если можешь, я сделаю заказ в знак благодарности)
 
  • Спасибо
Реакции: BAZAg
Большое человеческое спасибо. Еще не проверял но думаю то что нужно. Восстанови кворк если можешь, я сделаю заказ в знак благодарности)
Ничего не нужно - обычного "Спасибо" достаточно :)
Хорошего дня :)
 
  • Спасибо
Реакции: one и Wide
Решил добавить ещё вариант когда одним запросом нужно отправить сразу несколько файлов (кому-то просто может быть сразу не очевидно как это сделать...).
C#:
Развернуть Свернуть Копировать
string[] db_setting = new[] {
  string.Format("database={0}", db),
  string.Format(@"server={0}",ip),
  //string.Format(@"port={0}", "82"),
  string.Format(@"user id={0}", user),
  string.Format(@"password={0}", password)
};
 
string connect_db = string.Join("; ", db_setting);

var list = new List<byte[]>();
var file1 = File.ReadAllBytes(@"C:\Users\User\Desktop\text primer.xmlz");
var file2 = File.ReadAllBytes(@"C:\Users\User\Desktop\text primer.xmlz");
var file3 = File.ReadAllBytes(@"C:\Users\User\Desktop\text primer.xmlz");
list.Add(file1);
list.Add(file2);
list.Add(file3);


var val = new System.Collections.Specialized.OrderedDictionary();

for(int i=0;i<list.Count;i++) {
    string key = string.Format("f{0}",i);
    val.Add(key, list[i]);
}


string SQL = string.Format(@"INSERT INTO `testzenno`.`mytable` (`blobdata`) VALUES {0};",string.Join(",",val.Keys.Cast<string>().Select(x=>string.Format("(@{0})",x))));
return ZennoPoster.Db.ExecuteNonQuery(SQL, val, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,connect_db);
 
Вот, такой код должен сработать, перепроверил, у меня сработал.
C#:
Развернуть Свернуть Копировать
// таблица была в таком виде:
// CREATE TABLE `mytable` (`blobdata` blob ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
string[] db_setting = new[] {
  string.Format("database={0}", db),
  string.Format(@"server={0}",ip),
  //string.Format(@"port={0}", "82"),
  string.Format(@"user id={0}", user),
  string.Format(@"password={0}", password)
};

string connect_db = string.Join("; ", db_setting);

var file = File.ReadAllBytes(@"C:\Users\User\Desktop\text primer.xmlz");
var val = new System.Collections.Specialized.OrderedDictionary {{"file", file}};
string SQL = @"INSERT INTO `testzenno`.`mytable` (`blobdata`) VALUES (@file);";
return ZennoPoster.Db.ExecuteNonQuery(SQL, val, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,connect_db);
Посмотреть вложение 96978
Стесняюсь спросить. А какая версия майскуэль у тебя? Код один в один, ну кроме подключения и файла, результат 0, даже пустой строки нет.

Screenshot_309.png
 
Стесняюсь спросить. А какая версия майскуэль у тебя? Код один в один, ну кроме подключения и файла, результат 0, даже пустой строки нет.

Посмотреть вложение 96982
Хм... Фантастика....
96983
Я не следил за обновлениями MySQL, как поставил когда-то давно в 2015-2016 году - так и стоит до теперь.
Помню, в то время проблема была, если поставить не 5-й версии - то Зенно никак не подключалось (там какая-то другая технология паролей была введена).
А уже сейчас - я не работаю напрямую с базой через Зенно - предпочитаю просто собрать какой-то маленький PHP скриптик, который то и делает, что выполняет нужный запрос к базе - а уже к этому скриптику обращаюсь с помощью POST-GET запросов....

Но, может действительно проблема в версионности базы...
Жаль на моем компьютер докер не запускается, чтобы можно было быстро поднять нужную версию для проверки...
 
Последнее редактирование:
  • Спасибо
Реакции: Wide
Стесняюсь спросить. А какая версия майскуэль у тебя? Код один в один, ну кроме подключения и файла, результат 0, даже пустой строки нет.

Посмотреть вложение 96982
Пожалуйста, поставьте последним параметром true, и выполните код ещё раз.
Может в лог вернет что там за ошибка...
C#:
Развернуть Свернуть Копировать
return ZennoPoster.Db.ExecuteNonQuery(
SQL,
val,
ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,
connect_db,
true // этот параметр отвечает за игнорирование ошибок - его установить в true если нужно узнать что там за проблема...
);
 
Пожалуйста, поставьте последним параметром true, и выполните код ещё раз.
Может в лог вернет что там за ошибка...
C#:
Развернуть Свернуть Копировать
return ZennoPoster.Db.ExecuteNonQuery(
SQL,
val,
ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,
connect_db,
true // этот параметр отвечает за игнорирование ошибок - его установить в true если нужно узнать что там за проблема...
);
Сперва ругался на что большие данные

Screenshot_310.png

Поменял на лонгблуб

Вернул код обратно, запрос. также пусто. Картинка обычная.

1.jpeg
 
А нет, вставляет пустые записи

Screenshot_311.png
 
Да, проблема не в версии.
Взял 3 разных файла.
Вывел имя и размер в байтах.
В итоге - мой пример самый маленький оказался - из-за чего был записан в blob корректно.
Ваша картинка в 5 раз больше моего файла - вот и ошибка по размеру...
Ну, и PDF имеет ещё больше размер - там уже ругается что слишком большой запрос...
96992
Значит, нужен какой-то другой тип данных ячейки на longblob или mediumblob.
96993

Ну, и в настройке самой базы в конфиге нужно увеличить размер max_alowed_packet, вот первая инструкция с гугла.

96994
 
А нет, вставляет пустые записи

Посмотреть вложение 96991
А программа точно отображает данные blob корректно?
Может данные добавляются, а программа просто не умеет их отображать?
Очистите таблицу.
Добавьте одним запросом данные.
Вторым запросом - получите данные с базы.
По идее, blob сразу будет сконвертирован в base64, и мы должны получить строку, размером больше 0.
Если же ячейка действительно пустая - то мы не получим длинную строку base64...
 
Все я сделал, и лонгблуб (написал выше) и 64 мб у меня должно хватить.

Screenshot_313.png

Screenshot_312.png

Можете прикрепить своё изображение? Проверю с ним. Я уже на грани вернутся к записи в басе64)
 
Все я сделал, и лонгблуб (написал выше) и 64 мб у меня должно хватить.

Посмотреть вложение 96995

Посмотреть вложение 96997

Можете прикрепить своё изображение? Проверю с ним. Я уже на грани вернутся к записи в басе64)
Изображение я Ваше использовал. Вот, добавляю его сюда.
Поставил тип данных mediumblob.
Ошибка при добавлении Вашей картинки пропала.
97000
С базы данных получаю данные - и вижу, что картинка сохранена успешно.
97001

Повторите такую же процедуру - добавьте сначала.
А потом - получите.
Узнаем это ошибка программы отображения, или действительно данные не добавляются в базу.
 

Вложения

  • 1.jpeg
    1.jpeg
    95,1 KB · Просмотры: 0
  • Спасибо
Реакции: Wide
Можно затестить ещё вообще с ДЕМО-данными:
Добавить данные в базу:
Развернуть Свернуть Копировать
string[] db_setting = new[] {
  string.Format("database={0}", db),
  string.Format(@"server={0}",ip),
  //string.Format(@"port={0}", "82"),
  string.Format(@"user id={0}", user),
  string.Format(@"password={0}", password)
};

string connect_db = string.Join("; ", db_setting);

string path = @"C:\Users\User\Desktop\1.jpeg";
// var file = File.ReadAllBytes(path);

var file = new byte[]{1,2,3,4,5}; // вместо файла - имеем байты
project.SendInfoToLog(string.Join("|", file.Select(x=>x.ToString())));
// 1|2|3|4|5 - выводим в лог
var val = new System.Collections.Specialized.OrderedDictionary {{"file", file}};
string SQL = @"INSERT INTO `testzenno`.`mytable` (`blobdata`) VALUES (@file);";
return ZennoPoster.Db.ExecuteNonQuery(SQL, val, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,connect_db, true);

Получить данные с базы:
Развернуть Свернуть Копировать
string[] db_setting = new[] {
  string.Format("database={0}", db),
  string.Format(@"server={0}",ip),
  //string.Format(@"port={0}", "82"),
  string.Format(@"user id={0}", user),
  string.Format(@"password={0}", password)
};

string connect_db = string.Join("; ", db_setting);

string SQL ="SELECT * FROM `mytable` LIMIT 1";
var base64 = ZennoPoster.Db.ExecuteQuery(SQL, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,connect_db);
return string.Join("|", Convert.FromBase64String(base64).Select(x=>x.ToString()));

97005

Если все правильно, то результаты должны совпадать (то что записали в базу - должно быть тем, что считали с базы).
Ну, и после добавления этого маленького массива - можно посмотреть в программу, что она там показывает в этот момент.
У меня навикат показывает корректно, что я в поле записал 5 байт...
97006

В случае чего - пишите, продолжим разбираться.
Правда сейчас на 1-2 часика нужно отлучиться...

P.S. Можно ещё так попытаться добавлять данные, изначально отправлять в base64, и заставить базу переконвертировать в blob.
Но, это может существенно увеличить нагрузку на процессор сервера, на котором стоит база.
Также функция FROM_BASE64 не доступна на моей версии MySQL, доступна на более поздних версиях...
Пример кода набросал ниже (проверить не могу, так как моя версия не поддерживает FROM_BASE64 )
Хотя... Может оказаться что сохранит в 16-ричном виде, вместо blob...
Надо проверять...
C#:
Развернуть Свернуть Копировать
var file = new byte[]{1,2,3,4,5}; // вместо файла - имеем байты
string SQL = string.Format(@"INSERT INTO `testzenno`.`mytable` (`blobdata`) VALUES (FROM_BASE64('{0}'));", Convert.ToBase64String(file));
return ZennoPoster.Db.ExecuteNonQuery(SQL, null, ZennoLab.InterfacesLibrary.Enums.Db.DbProvider.MySqlClient,connect_db, true);
 
Последнее редактирование:
  • Спасибо
Реакции: Wide

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)