Гость
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выгрузка файла из поля bytea / 20 сообщений из 20, страница 1 из 1
12.11.2017, 16:13
    #39551728
dadon72
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Просьба помочь.
Просмотрел весь форум, ответа на мою задачу не нашел.

Цель: загрузка в поле bytea любых типов файлов, и при необходимости выгрузка и сохранение в ФС в первозданном виде.
(хранить файле в БД уже решено, требование такое)

1. кодировка БД:
CREATE DATABASE blobs
ENCODING = 'UTF8'
LC_COLLATE = 'Russian_Russia.1251'
LC_CTYPE = 'Russian_Russia.1251';

2. Таблица:
CREATE TABLE public.blobtable
(
_name character varying(100),
_blob bytea
);

3. загрузка файла происходит нормально:
INSERT INTO blobtable VALUES ('summ_rs.pdf', pg_read_binary_file('summ_rs.pdf'));

4. тестирование:
SELECT _name, length(_blob) as size, _blob as blobs FROM blobtable;
Объем файла (length) показывает как есть в действительности, а вот сам объект bytea отображается и сохраняется в шестнадцатеричном виде (испытывал на текстовом файле и в других типах).

пробовал использовать "encode" с различными кодировками ('hex'/'base64'/'escape'), ничего не получилось
поколдовал с "convert_from" пришел к выводу что он здесь не причем, ожидаемых результатов не добился

Вопрос:
Как можно добиться того чтобы база возвращала сохраненные файлы без изменения содержания. Что я мог не учесть?

Заранее спасибо.
...
Рейтинг: 0 / 0
12.11.2017, 18:45
    #39551773
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
dadon72,

у всех возвращает, а у него вишь ли не возвращает.
и пдф не текстовый файл, и база байтеа не обязана "отображать", пока вы её специально об этом не попросите. и конверт работает, если там лежит то, что должно и так, как должно:
Код: sql
1.
2.
3.
select 
'тест однако'::bytea
,convert_from('тест однако'::bytea,'UTF8');



и вообще.

проще всего сохранять приложением (или тем же плперлом). но и админпаком сохраняли и лажобъек--функциями и даже COPY с обрезкой заголовка срабатывал. всё на форуме есть. ищите.
...
Рейтинг: 0 / 0
12.11.2017, 18:57
    #39551776
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
dadon72,
link 2 link and COPY/tail--trick
...
Рейтинг: 0 / 0
12.11.2017, 18:58
    #39551777
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
qwwqdadon72,
link 2 link and COPY/tail--trick
18605051

линк потерялся при правке
...
Рейтинг: 0 / 0
12.11.2017, 19:08
    #39551778
dadon72
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
qwwq
у всех возвращает, а у него вишь ли не возвращает.
и пдф не текстовый файл, и база байтеа не обязана "отображать", пока вы её специально об этом не попросите. и конверт работает, если там лежит то, что должно и так, как должно:
Код: sql
1.
2.
3.
select 
'тест однако'::bytea
,convert_from('тест однако'::bytea,'UTF8');



и вообще.

проще всего сохранять приложением (или тем же плперлом). но и админпаком сохраняли и лажобъек--функциями и даже COPY с обрезкой заголовка срабатывал. всё на форуме есть. ищите.

Спасибо конечно, "convert_from" использовать я и сам додумался, да вот проблема в том что это касается ТОЛЬКО текстовых файлов. А попробуйте ка Вы ,тот же ПДФ загрузить в bytea и выгрузить в ФС (или любой бинарный файл).

На форуме много беседы около да вокруг моей проблемы,
по данной задаче я и в мануале ничего не нашел (а может и не заметил)

сохранять в файл буду через переменный в ПХП, а до этого я должен увидеть адекватный результат на PSQL
...
Рейтинг: 0 / 0
13.11.2017, 03:42
    #39551899
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
dadon72сохранять в файл буду через переменный в ПХП, а до этого я должен увидеть адекватный результат на PSQL

Как вы себе представляете адекватный pdf в psql ???
...
Рейтинг: 0 / 0
13.11.2017, 11:48
    #39552068
Lonepsycho
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
dadon72,

в общем, никаких проблем. пихаете в бытеа из пехапе енкодив в бейс64, и декодя в пг, ну и когда надо, делая наоборот.
...
Рейтинг: 0 / 0
13.11.2017, 12:28
    #39552107
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Lonepsychodadon72,

в общем, никаких проблем. пихаете в бытеа из пехапе енкодив в бейс64, и декодя в пг, ну и когда надо, делая наоборот.

Эээ, можно конечно, но нафига? если base64 то это уже не bytea а text будет. А bytea для работы с двоичными данными и все что надо для работы с ними напрямую без всяких base64 - вполне доступно в базе.
...
Рейтинг: 0 / 0
13.11.2017, 14:01
    #39552205
Lonepsycho
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Maxim Boguk,

bytea наш веб девелопер использует как транспорт между пг и ПеХаПе. шоб нормально "настоящие нолики" обрабатывались. незнаю деталей, могу ошибатся, если правильно понял его рассказ, то изза драйвера пехапешного конверсии ему нужны.
...
Рейтинг: 0 / 0
13.11.2017, 14:04
    #39552208
Lonepsycho
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Maxim Boguk,

т.е. поле в БД bytea при вставке в ДБ делается декоде, при селекте енкоде... ну а там, в пхп, уже что ему заблагорассудиться...
...
Рейтинг: 0 / 0
13.11.2017, 16:24
    #39552350
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
LonepsychoMaxim Boguk,

т.е. поле в БД bytea при вставке в ДБ делается декоде, при селекте енкоде... ну а там, в пхп, уже что ему заблагорассудиться...


он наверное из соапа данные кладёт -- они там именно в бейз64 лежат.
...
Рейтинг: 0 / 0
13.11.2017, 18:23
    #39552457
dadon72
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Maxim BogukКак вы себе представляете адекватный pdf в psql ???

в psql в основном текстовый файлы тестирую, а для pdf мне достаточно сначала визуально запомнить а далее не стоит труда объект присвоить переменной ПХП и выгрузить его через HTML Header в ФС клиента


Lonepsychoв общем, никаких проблем. пихаете в бытеа из пехапе енкодив в бейс64, и декодя в пг, ну и когда надо, делая наоборот.

т.е. поле в БД bytea при вставке в ДБ делается декоде, при селекте енкоде... ну а там, в пхп, уже что ему заблагорассудиться..


стеснялся говорить но почему то INSERT не берет decode. может в настройках дело, не было времени его изучать


Maxim BogukЭээ, можно конечно, но нафига? если base64 то это уже не bytea а text будет. А bytea для работы с двоичными данными и все что надо для работы с ними напрямую без всяких base64 - вполне доступно в базе.
Согласен.

qwwqон наверное из соапа данные кладёт -- они там именно в бейз64 лежат.
по подробней можно "из соапа". Мануал укажите пожалуйста

Спасибо за отзывы
...
Рейтинг: 0 / 0
14.11.2017, 06:34
    #39552600
dadon72
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Открываю карты.
Моя задача перевести приложение на ПХП из базы MySQL на Postgresql.

Так вот в MySQL есть функция LOAD_FILE() посредством которого можно засовывать в поле любые бинарные файлы, любых размеров, без разницы кодировок. Пример:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
if($_FILES['file']['error']==0&&$_FILES['file']['size']>0){
		$name=sanitizeMySQL($_FILES['file']['name']);
		$path=str_replace('\\','/',$_FILES['file']['tmp_name']);
		$type=$_FILES['file']['type'];
		$size=$_FILES['file']['size'];
		mysqli_query($db,
"INSERT INTO books_files(date_ins,file_name,file_blob,file_type,file_size) VALUES('$date_ins','$name',COMPRESS(LOAD_FILE('$path')),'$type',$size)");
	}else exit($_FILES['file']['error']);

(ёще и компрессировал)

А когда надо было, можно эти данные присвоить в переменную ПХП и загружать через браузер. Пример:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
if(isset($_GET['id'])){
	require_once '../lib/connect.php';
	$kod_files=sanitizeMySQL($_GET['id']);
	$query=mysqli_query($db,"SELECT file_name,UNCOMPRESS(file_blob)'file',file_type,file_size FROM books_files WHERE kod_files='$kod_files'");
	$row=mysqli_fetch_assoc($query);
	mysqli_free_result($query);
	mysqli_query($db,"UPDATE books_files SET save_count=save_count+1 WHERE kod_files='$kod_files'");
	mysqli_close($db);
	header('Content-Type: '.$row['file_type']);
	header('Content-Length: '.$row['file_size']);
	header('Content-Disposition: Attachment; FileName="'.$row['file_name'].'"');
	echo $row['file'];
}else exit('Forbidden act!!!');

Вроде просто и ясно. Приложение работает четко. Без декоде и енкоде и всяких конверт_фром и конверт_ту.

Вот перевести этот механизм на Postgresql получается гемор.
1. При попытке просто загрузить и выгрузить получается изменение битности (по моему). Ничего не получилось
2. При использовании decode, его почему то Insert не берет. Слепо пробовал извлекать через encode со всеми параметрами. Ничего не получилось
3. Использовал convert_from, так он бинарные файлы преобразовывал в текстовый файл, он хорошо работает с текстовыми файлами, меня это не устраивает.

Помогите пожалуйста.

Если ничего не получится, придется убеждать руководство по преимуществах MySQL и оставить задачу как есть, чего очень не хочется.
...
Рейтинг: 0 / 0
14.11.2017, 06:49
    #39552601
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
...
Рейтинг: 0 / 0
14.11.2017, 06:59
    #39552602
dadon72
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Maxim Boguk,

Спасибо. Позже попробую. О результате сообщу.
...
Рейтинг: 0 / 0
15.11.2017, 05:17
    #39553192
dadon72
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Спасибо всем. Решил средствами ПХП.
Для того чтобы пользовались другие, выложу примеры. Надеюсь что для новичков как я, это может пригодится.

Загрузка в базу:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
<?php
if(isset($_FILES['file']))
	if($_FILES['file']['error']==0&&$_FILES['file']['size']>0){
		$db=pg_connect("host=localhost dbname=blobs user=вася password=пупкин")or die("Невозможно подключиться");
		$name=$_FILES['file']['name'];
		$escaped=pg_escape_bytea(file_get_contents($_FILES['file']['tmp_name']));
		$type=$_FILES['file']['type'];
		$size=$_FILES['file']['size'];
		pg_query("INSERT INTO blobtable(_name,_blob,_type,_size) VALUES('$name','$escaped','$type',$size)");
	}else exit($_FILES['file']['error']);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
 <fieldset><legend>Загрузка файла</legend>
  <form method="post" enctype="multipart/form-data">
   <input type="file" name="file"/><input type="submit" value="Загрузка"/>
  </form>
 </fieldset>
</body>
</html>



Выгрузка из базы:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
$db=pg_connect("host=localhost dbname=blobs user=вася password=пупкин")or die("Невозможно подключиться");

$filename='Имя_файла.ХХХ';

$query=pg_query("SELECT _name,_blob,_type,_size FROM blobtable WHERE _name='$filename'");
 
$row=pg_fetch_assoc($query);
pg_free_result($query);
pg_close($db);

header('Content-Type: '.$row['_type']);
header('Content-Length: '.$row['_size']);
header('Content-Disposition: Attachment; FileName="'.$row['_name'].'"');
echo pg_unescape_bytea($row['_blob']);



Конечно в этом решении есть недостатки. Большой из них - во время загрузки и выгрузки Аппач(ПХП) пожирает много памяти(особенно в больших файлах). при малой оперативки сервера и большом количестве обращений к объектам, сервер может сойти с ума. (Это конечно в пользу сторонников хранения файлов вне базы данных, в файловой системе)
Облегчило бы задачу выполнение кодировки-декодировки и соответственно обмен файлами, своими средствами СУБД, но у меня не получилось
...
Рейтинг: 0 / 0
15.11.2017, 10:42
    #39553300
Lonepsycho
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
dadon72,

ещё одна причина по которой мы енкодим именно в бейс64

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT 
  length(CAST(v.t AS BYTEA)) AS raw,
  length(encode(CAST(v.t AS BYTEA), 'base64')) AS base64,
  length(encode(CAST(v.t AS BYTEA), 'hex')) AS hex
FROM 
  (VALUES 
    ('this is some, not very long, test string, to see how encoding of bytes differ'::TEXT
  )) AS v(t)



pg_escape_bytea(), судя по документации, превращает в восмеричную форму, что, по моему, будет ещё менее компактно.
ИМХО, конечно.
...
Рейтинг: 0 / 0
15.11.2017, 12:45
    #39553395
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
dadon72,

Тогда вам надо не в сторону bytea смореть а в сторону large objects в postgresql
и в сторону функций:
https://secure.php.net/manual/en/function.pg-lo-read-all.php
и связанных с ней.

PS: не вижу вообще никаких попыток использовать гугл или хотя бы доку по PHP с вашей стороны :(.
...
Рейтинг: 0 / 0
15.11.2017, 18:00
    #39553776
dadon72
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
Maxim Bogukdadon72,

Тогда вам надо не в сторону bytea смореть а в сторону large objects в postgresql
и в сторону функций:
https://secure.php.net/manual/en/function.pg-lo-read-all.php
и связанных с ней.

В данное время я оцениваю варианты хранения объектов

1. Хранить в поле bytea в записях внешней таблицы.
Преимущество в управлении данными, например:
- при удалении первичных записей, без мороки каскадом удаляются и записи в привязанных таблицах;
- удобнее экспортировать и импортировать
Недостатки
- сложности при кодировании, конвертировании и использование в этих целях инструментарий приложения.
- ограничении с выделяемыми ресурсами памяти и процессора

2. Хранить в large objects
Преимущества:
- работает быстро
- никаких проблем с кодированием и конвертированием
Недостатки:
- нет автоматической связи с таблицами, надо будет ОИД в запись пихать и самому контролировать соотношение первичных записей с хранимыми объектами.
- не представляю как экспортировать (сомневаюсь на неизменность ОИД объектов при восстановлении)

3. хранить в файлах
Преимущества:
- работает быстро
- никаких проблем с кодированием и конвертированием
Недостатки:
- нет автоматической связи с таблицами, надо будет обращаться в файловую систему(копирование, создание папок, переименовывание, удаление и др.) и самому контролировать соотношение первичных записей с хранимыми объектами.
- надо сисадминов тревожить для доступов.

это моё субъективное мнение. может в каждом варианте есть еще преимущества и недостатки, это то что я обнаружил.
В общем еще изучаю.

Maxim BogukPS: не вижу вообще никаких попыток использовать гугл или хотя бы доку по PHP с вашей стороны :(.

не всегда. хочу как можно реже использовать функции PHP
...
Рейтинг: 0 / 0
16.11.2017, 04:36
    #39553966
Maxim Boguk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выгрузка файла из поля bytea
dadon72,

>>- не представляю как экспортировать (сомневаюсь на неизменность ОИД объектов при восстановлении)
При dump/restore OID у large objects сохраняются.
Иначе совершенно не ясно как пришлось бы поддерживать связь между OID в таблице и LO при восстановлении базы из dump.

>>- нет автоматической связи с таблицами, надо будет ОИД в запись пихать и самому контролировать соотношение первичных записей с хранимыми объектами.
Частично вам поможет https://www.postgresql.org/docs/9.6/static/lo.html с этим

>>3. хранить в файлах
Преимущества:
- работает быстро

Тут надо понимать что идея с хранением файлов с базе работает только для очень маленьких и не нагруженных проектов (ну или когда ресусы железа девать некуда).
Так как передача файла браузеру по трудоемкости для проекта где то так расположена:
bytea : LO : static file / nginx : public CDN как 100 : 100 : 10 : 1
Т.е. даже bytea будет по ресусам сервера на порядок и более дороже чем отдача статических файлов напрямую nginx ом.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выгрузка файла из поля bytea / 20 сообщений из 20, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]