использование \ COPY с BINARY для lo_export в postgreSQL на серверной системе - PullRequest
2 голосов
/ 16 февраля 2012

Я работаю с PostgreSQL 9 для приложения, у меня есть база данных с таблицей видов. где я храню информацию о видах рыб вместе с изображением видов. стол

       CREATE TABLE fishes
               (
                  fishes character varying(7) NOT NULL,
                  speciesimages oid,
                  CONSTRAINT species_pkey PRIMARY KEY (species)
                 )
                   WITH (
                       OIDS=TRUE
               );

я использую

INSERT INTO species(fishes,fishesimages VALUES('01',lo_import('C://01.jpg'));

Для хранения изображений в базе данных.

для получения изображений, которые я использую

       SELECT lo_export(fishes.fishesimages,'c://outimage.jpg') 
       FROM   fishes
       WHERE  fishes= '01'; 

Это прекрасно работает, когда хост Localhost , но когда это сервер, я не могу использовать путь c://, так как он может не существовать в системе сервера и у меня нет разрешений в любом случае.

поэтому я решил использовать

\ COPY

вот так

"C:\Program Files\PostgreSQL\9.0\bin\psql.exe" -h 192.168.1.101 -p 5432 -d myDB -U DB_admin -c  "\COPY (SELECT lo_export(fishes.fishesimages,'01.jpg') FROM   fishes WHERE  species = '01') TO 'C://leeImage.jpeg' WITH BINARY";

но это создает файл изображения, но когда я открываю его, недопустимое изображение enter image description here

Может кто-нибудь сказать мне, как использовать функцию lo_export с сервера сервера и создать образ на клиентском компьютере?

1 Ответ

2 голосов
/ 16 февраля 2012

В основном:

  1. lo_export попросит сервер записать файл локально (всегда)
  2. \copy будет преобразован psql в команду COPY ... TO STDOUT, а выходные данные будут записаны в указанный файл. (То, что записано в этот файл, это результат из select отчета, который вы делали раньше)

Таким образом, вы можете не использовать lo_export таким образом, он всегда будет записывать файл в файловую систему сервера.

Конечно, вы можете решить эту проблему, просто выполнив запись на общий диск, а затем прочитайте файл с этого диска. Гадкий, но эффективный ИМХО.

Для некоторых последних версий psql (не уверен, когда это было введено) существует команда \lo_export psql, которая принимает OID и имя файла, например ::

\lo_export 28914648 testfile

Однако вам нужно каким-то образом получить OID файла в сценарии ...

Вы можете написать такую ​​функцию PL / PGsql, чтобы вывести файл в виде байта:

CREATE OR REPLACE FUNCTION getfiledata(lobjid oid) RETURNS bytea
  STRICT STABLE LANGUAGE plpgsql AS $$
DECLARE
  fd int4;
  imgsize int4;
  INV_READ int4 := 262144;
  SEEK_SET int4 := 0;
  SEEK_END int4 := 2;
BEGIN
  SELECT lo_open(lobjid, INV_READ) INTO fd;
  PERFORM lo_lseek(fd, 0, SEEK_END);
  SELECT lo_tell(fd) INTO imgsize;
  PERFORM lo_lseek(fd, 0, SEEK_SET);
  RETURN loread(fd, imgsize);
END;
$$;

Теперь вызов этой функции с OID большого объекта вернет его содержимое в виде значения байта. Таким образом, вы можете вызвать эту функцию в команде COPY, и она вернет данные файла ... и с помощью \copy будет отправлена ​​клиенту.

В наши дни, как правило, рекомендуется использовать bytea столбцы напрямую, а не интерфейс большого объекта (bytea была представлена ​​намного позже). PostgreSQL автоматически перемещает большие значения во внешнее хранилище («таблицы TOAST») и также сжимает их (если режим хранения не установлен как «внешний», чтобы подавить это, что, вероятно, является правильным решением для изображений JPEG и т.д.)

РЕДАКТИРОВАТЬ: \lo_export Попробуйте это с commandprompt.com

 `"C:\Program Files\PostgreSQL\9.0\bin\psql.exe" -h 192.168.1.101 -p 5432 -d myDB -U DB_admin -c  "\lo_export 19135 'C://leeImage.jpeg' ";`

где число 19135 - это OID вида, изображение которого я хочу в клиентской системе ... OID, который вы можете получить из таблицы fishes fishesimages OID используйте OID в приведенном выше коде, и вы можете использовать OID для получения изображений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...