powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Хранение изображения
12 сообщений из 12, страница 1 из 1
Хранение изображения
    #38906568
alextashk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!

Есть таблица
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
  	CREATE TABLE "d_picture"  
  	(  
  	id character(30) PRIMARY KEY,  
  	dtadd timestamp without time zone DEFAULT now(),  
  	dtizm timestamp without time zone DEFAULT now(),  
  	idparent character(30),   
  	cpath character(254),   
  	cpic bytea,   
  	copis character(50)  
  	)  
  	WITH (  
  		OIDS=TRUE  
  		);  
  	CREATE INDEX d_picture_parent ON "d_picture" (idparent); 



Пытаюсь загнать файл в поле cpic через VFP
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 SCAN  
  	lcPath1 = '"' + gcPath + 'pictures\' + d_picture.idParent + '\' + ALLTRIM(d_picture.cPath1) + '"'  
  	IF FILE(lcPath1) THEN  
  		lcFile = CAST(FILETOSTR(lcPath1)  as BLOB)
  		TEXT TO lcSQL TEXTMERGE PRETEXT 15 NOSHOW  
  			INSERT INTO d_picture(id, dtadd, dtizm, idparent, cpath, cpic, copis)   
  				VALUES (?d_picture.id, ?d_picture.dtadd, ?d_picture.dtizm,  
  					?d_picture.idparent, ?d_picture.cpath, ?lcfile, ?d_picture.copis);  
  		ENDTEXT  
  		lnOk = my_SQL(lcSQL, '', .T., '')  
  	ENDIF  
  ENDSCAN  



PostgreSQL ругается, говорит, что нет типа lo

что делать?
...
Рейтинг: 0 / 0
Хранение изображения
    #38906576
alextashk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ошибка - 1526
тип lo не существует

postgresql 9.4 на windows
...
Рейтинг: 0 / 0
Хранение изображения
    #38906630
alextashk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тип lo добавил!

postgresql ругнулся на не соответствие типов lo и bytea

если в таблице поправить тип cPic с bytea на lo - файлы уходят на сервер, но как их оттуда вытащить?

SELECT id, lo_get(cPic) FROM d_picture WHERE id = '111'

Через SQLEXEC - отрабатывает без ошибок, но не создаёт таблицу на стороне VFP

в общем 2 вопроса:
1. Если хранить файлы на сервере в типе lo - как их вытащить?
2. Если хранить файлы на сервере в типе bytea - как их туда загнать
...
Рейтинг: 0 / 0
Хранение изображения
    #38906843
Фотография grufos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alextashk,

киньте пожалуйста ваш код подключения к PostgreSQL и чтения возвращаемого рекордсета
я хотел бы провести у себя эксперименты
...
Рейтинг: 0 / 0
Хранение изображения
    #38906987
alextashk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grufos,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
gcConnect = "DRIVER={PostgreSQL ODBC Driver(ANSI)};" + ;  
	"SERVER=localhost;" + ;  
	"PORT=2222;" + ;  
	"UID=dd;" + ;  
	"PWD=dd;" + ;  
	"DATABASE=dd;" + ;
	"BOOLSASCHAR=0"
    
gnHandle = SQLSTRINGCONNECT( gcConnect)  



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
TEXT
   SELECT id, dtadd, dtizm, idparent, cpath, lo_get(cpic) as dd, copis
    FROM f_picture
     WHERE f_picture.id ='11' ;
ENDTEXT
  lnOk = my_SQL(lcSQL, 'll_dd', .T., '')
  SELECT ll_dd
  COPY TO d:\ff



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
FUNCTION my_SQL
LPARAMETERS tcText, tcAlias, tlError, tcError
WAIT WINDOW tcError NOWAIT
IF gnHandle < 1 THEN
	gnHandle = SQLSTRINGCONNECT(gcConnect)
	IF gnHandle < 1 THEN
	* &#206;&#225;&#240;&#224;&#225;&#238;&#242;&#234;&#224; &#238;&#248;&#232;&#225;&#234;&#232; &#239;&#238;&#228;&#234;&#235;&#254;&#247;&#229;&#237;&#232;&#255;
		lcConnect = gcConnect
		lnBeg = AT('UID=', lcConnect) + 2
		FOR lnPer = 1 TO 20
			IF lnBeg + lnPer < LEN(lcConnect) .AND. SUBSTR(lcConnect, lnBeg + lnPer, 1) THEN
				lcConnect = LEFT(lcConnect, lnBeg + lnPer) + 'X' + RIGHT(lcConnect, LEN(lcConnect) - lnBeg - lnPer - 1)
			ELSE
				EXIT
			ENDIF
		NEXT 
		lnBeg = AT('PWD=', lcConnect) + 2
		FOR lnPer = 1 TO 20
			IF lnBeg + lnPer < LEN(lcConnect) .AND. SUBSTR(lcConnect, lnBeg + lnPer, 1) THEN
				lcConnect = LEFT(lcConnect, lnBeg + lnPer) + 'X' + RIGHT(lcConnect, LEN(lcConnect) - lnBeg - lnPer - 1)
			ELSE
				EXIT
			ENDIF
		NEXT 
		lnOk = err_SQL('&#207;&#238;&#228;&#234;&#235;&#254;&#247;&#229;&#237;&#232;&#229;' + CHR(10) + CHR(13) + lcConnect, .T.)
	ENDIF
ENDIF
USE IN SELECT(tcAlias)
lnOk = SQLEXEC(gnHandle, tcText, tcAlias)
IF lnOk < 1 THEN
	lnOk = err_SQL(tcError + CHR(13) + CHR(10) + tcText, tlError)
ENDIF
WAIT CLEAR
RETURN lnOk
...
Рейтинг: 0 / 0
Хранение изображения
    #38907000
Фотография grufos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alextashk,
спасибо, разбираюсь...
...
Рейтинг: 0 / 0
Хранение изображения
    #38907068
Фотография grufos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alextashk,

в какой кодировке у вас БД?
Так как вы работаете с Foxpro, то могу предположить, что 'WIN1251'
я попробовал поработать с типом bytea
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
_lcConn = 'DRIVER={PostgreSQL ODBC Driver(ANSI)};DATABASE='+_lcBase+';SERVER='+_lcServer+';PORT=5432;Uid='+_lcUser+';'+';Pwd='+_lcPass+';B9=1;"'
_lnHandle = SQLSTRINGCONNECT(_lcConn)
IF _lnHandle < 0  && нет соединения с сервером

    * анализируем ошибку
	DO ErrHand with "Не удалось установить соединение с сервером."
	
    ON ERROR &_lcOldError			&& восстанавливаем обработчик ошибок
    RETURN .F.
ELSE   
	* есть соединение

    * устанавливаем свой обработчик ошибок
	ON ERROR DO ErrHand with ""
    * выполняемая команда на сервере
    _lcCommand = "insert into d_picture (id, cpath, cpic) values(1, 'c:\temp\picture\94.log','Тестовая строка');"
	SQLEXEC(_lnHandle, _lcCommand)

    _lcCommand = "select * from d_picture"
	SQLEXEC(_lnHandle, _lcCommand)
	
    SQLDISCONNECT(_lnHandle)				&& закрываем соединение
ENDIF


в итоге в курсоре SqlResult в Memo поле получил исходную строку.
У вас так работает?
...
Рейтинг: 0 / 0
Хранение изображения
    #38907115
Фотография grufos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alextashk,
вот так тоже получаю в результате исходный файл
Код: vbnet
1.
2.
3.
4.
5.
6.
    _lcFile = FILETOSTR('c:\temp\94.log')
    _lcCommand = "insert into d_picture (id, cpath, cpic) values(1, 'c:\temp\94.log',?_lcFile);"
	SQLEXEC(_lnHandle, _lcCommand)

    _lcCommand = "select * from d_picture"
	SQLEXEC(_lnHandle, _lcCommand)
...
Рейтинг: 0 / 0
Хранение изображения
    #38907534
alextashk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grufos,

Спасибо за интерес к теме.

У меня, с помощью более опытных товарищей (точнее слямзил решение у них)
1. Подключение
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
gcConnect = "DRIVER={PostgreSQL ODBC Driver(ANSI)};" + ;  
	"SERVER=localhost;" + ;  
	"PORT=dd;" + ;  
	"UID=dd;" + ;  
	"PWD=dd;" + ;  
	"DATABASE=dd;" + ;
	"BOOLSASCHAR=0;" + ;
	"C7=1"



2.Закачка на сервер
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
	lcFile= CAST(FILETOSTR(lcPath1) as blob)

	TEXT TO lcSQL TEXTMERGE PRETEXT 15 NOSHOW

		INSERT INTO f_picture(id, dtadd, dtizm, idparent, cpath, cpic, copis) 
			VALUES (?f_picture.id, ?f_picture.dtadd, ?f_picture.dtizm,
				?f_picture.idparent, ?f_picture.cpath, ?lcPath1, ?f_picture.copis);
	ENDTEXT
		lnOk = my_SQL(lcSQL, '', .T., '')



3. Закачка на машину

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    Local _CA  
    _CA=Createobject("CursorAdapter")  
    _CA.Alias="D_zagot"  
    _CA.DataSourceType="ODBC"  
    _CA.Datasource=gnHandle  
    _CA.SelectCmd="SELECT id, dtadd, dtizm, idparent, cpath, cpic, copis FROM fond_picture WHERE id = '11'"  
    _CA.CursorSchema="id C(30), dtadd T, dtizm T, idparent C(30), cpath C(254), cpic W, copis C(50)"  
    _CA.MapBinary=.T.  
    _CA.SendUpdates=.F.  
    _CA.UseCursorSchema=.T.  
    IF _CA.CursorFill(.T.,.F.)  
		lnOk = STRTOFILE(d_zagot.cPic, "d:\pic.jpg")
	ENDIF 



Всем спасибо - вопрос решен
...
Рейтинг: 0 / 0
Хранение изображения
    #38907915
Фотография grufos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alextashk,

а откуда такой параметр С7 ?
по документации у нас всего
https://odbc.postgresql.org/howto-accessvba.html
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
'   PG_ODBC_PARAMETER           ACCESS_PARAMETER
'   *********************************************
'   READONLY                    A0
'   PROTOCOL                    A1
'   FAKEOIDINDEX                A2  'A2 must be 0 unless A3=1
'   SHOWOIDCOLUMN               A3
'   ROWVERSIONING               A4
'   SHOWSYSTEMTABLES            A5
'   CONNSETTINGS                A6
'   FETCH                       A7
'   SOCKET                      A8
'   UNKNOWNSIZES                A9  ' range [0-2]
'   MAXVARCHARSIZE              B0
'   MAXLONGVARCHARSIZE          B1
'   DEBUG                       B2
'   COMMLOG                     B3
'   OPTIMIZER                   B4  ' note that 1 = _cancel_ generic optimizer...
'   KSQO                        B5
'   USEDECLAREFETCH             B6
'   TEXTASLONGVARCHAR           B7
'   UNKNOWNSASLONGVARCHAR       B8
'   BOOLSASCHAR                 B9
'   PARSE                       C0
'   CANCELASFREESTMT            C1
'   EXTRASYSTABLEPREFIXES       C2
...
Рейтинг: 0 / 0
Хранение изображения
    #38908399
Лопата
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grufosalextashk,

а откуда такой параметр С7 ?
по документации у нас всего
https://odbc.postgresql.org/howto-accessvba.html
<>не по доке, а по "how to"
никто на этом клочке исчерпывающего списка не обещал.

вот тут https://odbc.postgresql.org/ можно попасть на https://odbc.postgresql.org/docs/config.html ,там, в advanced options есть параметр

клочокBytea as LO: Allow the use of bytea columns for Large Objects.

сл-но, последовательность действий такая -- настраиватете этот крыжик в dsn, читаете результат глазом в файле -- выставляете такой же при подключении из vfp.

вообще дока оставляет желать. тут доку на сам пж 9.4. причёсывать похоже начали -- пока плююсь.
...
Рейтинг: 0 / 0
Хранение изображения
    #38908717
Фотография grufos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
лопата,

подвожу итоги для будущих исследователей (прошу прощения за повтор)

доки по ODBC драйверу
https://odbc.postgresql.org/ - главная страница, на ней есть разные справки типа "как это сделать" psqlODBC HOWTOs (лучше просмотреть все эти примеры)
https://odbc.postgresql.org/docs/config.html - более менее подробное описание
https://odbc.postgresql.org/docs/config-opt.html - коды для использования в connection string

и пример программы показывающей использование типов данных bytea и lo для хранения больших объемов в таблицах. Инструмент Visual Foxpro (хоть и древний, но простой и рабочий)
основная идея - если достаточен объем в одном поле до 1ГБ, то можно обойтись типом bytea. В другом случае только lo (стандартное расширение PostgreSQL)
Для варианта с bytea нужно в connection string установить C7=1 (Bytea as LO: Allow the use of bytea columns for Large Objects.).
пример:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
************************************************************************************
LOCAL _lcServer, _lcUser, _lcPass, _lcConn, _lnHandle, _lcCommand, _CA_lo, _CA_bytea

CLEAR

_lcServer = "localhost"			&& сервер
_lcBase   = "test"				&& база данных
_lcUser   = "postgres"			&& пользователь
_lcPass   = "12345678"			&& пароль


* подключение через ODBC драйвер
_lcConn = 'DRIVER={PostgreSQL ODBC Driver(ANSI)};DATABASE='+_lcBase+';SERVER='+_lcServer+';PORT=5432;Uid='+_lcUser+';'+';Pwd='+_lcPass+';B9=0;C7=1"'
_lnHandle = SQLSTRINGCONNECT(_lcConn)
IF _lnHandle < 0  && нет соединения с сервером

    * анализируем ошибку
	DO ErrHand with "Не удалось установить соединение с сервером."
	
    RETURN .F.
ELSE   
	* есть соединение

    * устанавливаем свой обработчик ошибок
	ON ERROR DO ErrHand with ""

	*!* не забудьте добавить расширение - CREATE EXTENSION lo;
	*!*	CREATE TABLE d_picture
	*!*	(
	*!*	  id 		character(30) NOT NULL,
	*!*	  dtadd 	timestamp without time zone NOT NULL DEFAULT now(),
	*!*	  dtizm 	timestamp without time zone NOT NULL DEFAULT now(),
	*!*	  idparent	character(30),
	*!*	  cpath		character(254) NOT NULL,
	*!*	  cpic		bytea,
	*!*	  cpic_lo	lo,
	*!*	  copis		character(50),
	*!*	  CONSTRAINT d_picture_pkey PRIMARY KEY (id)
	*!*	)

	SQLEXEC(_lnHandle, 'truncate table d_picture')

	* работа с bytea

    * выполняемая команда на сервере
    _lbFile = CAST(FILETOSTR('c:\temp\edb_pgagent.exe') as BLOB)
    _lcCommand = "insert into d_picture (id, cpath, cpic) values(1, 'c:\temp\edb_pgagent.exe',?_lbFile);"
	SQLEXEC(_lnHandle, _lcCommand)

    _CA_bytea=Createobject("CursorAdapter")  
    _CA_bytea.Alias="d_bytea"  
    _CA_bytea.DataSourceType="ODBC"  
    _CA_bytea.Datasource=_lnHandle
    _CA_bytea.SelectCmd="SELECT id, dtadd, dtizm, idparent, cpath, cpic, copis FROM d_picture WHERE id = '1'"  
*    _CA_bytea.CursorSchema="id C(30), dtadd T, dtizm T, idparent C(30), cpath C(254), cpic M nocptrans, copis C(50)"  && M nocptrans приведен для примера, тоже работает, но я рекомендую BLOB
    _CA_bytea.CursorSchema="id C(30), dtadd T, dtizm T, idparent C(30), cpath C(254), cpic W, copis C(50)"  
    _CA_bytea.MapBinary=.T.  
    _CA_bytea.SendUpdates=.F.  
    _CA_bytea.UseCursorSchema=.T.  
    IF _CA_bytea.CursorFill(.T.,.F.)  
		_lnOk = STRTOFILE(d_bytea.cpic, 'c:\temp\edb_pgagent.bytea')
	ENDIF 


	* работа с lo типом

    * выполняемая команда на сервере
    _lbFile = CAST(FILETOSTR('c:\temp\edb_pgagent.exe') as BLOB)
    _lcCommand = "insert into d_picture (id, cpath, cpic_lo) values(2, 'c:\temp\edb_pgagent.exe',?_lbFile);"
	SQLEXEC(_lnHandle, _lcCommand)

    _CA_lo=Createobject("CursorAdapter")  
    _CA_lo.Alias="d_blob"  
    _CA_lo.DataSourceType="ODBC"  
    _CA_lo.Datasource=_lnHandle
    _CA_lo.SelectCmd="SELECT id, dtadd, dtizm, idparent, cpath, cpic_lo, copis FROM d_picture WHERE id = '2'"  
    _CA_lo.CursorSchema="id C(30), dtadd T, dtizm T, idparent C(30), cpath C(254), cpic_lo W, copis C(50)"  
    _CA_lo.MapBinary=.T.  
    _CA_lo.SendUpdates=.F.  
    _CA_lo.UseCursorSchema=.T.  
    IF _CA_lo.CursorFill(.T.,.F.)  
		_lnOk = STRTOFILE(d_blob.cpic_lo, 'c:\temp\edb_pgagent.lo')
	ENDIF 
	
    SQLDISCONNECT(_lnHandle)				&& закрываем соединение
ENDIF

* восстанавливаем обработчик ошибок
ON ERROR

RETURN .T.
************************************************************************************

*----------------------------------------------------------------------------------------
* Обработка ошибки
*----------------------------------------------------------------------------------------
PROCEDURE ErrHand
LPARAMETERS _lcTextMessage
*----------------------------------------------------------------------------------------
* _lcTextMessage - пользовательское сообщение о текущем выполняем процессе
*
* Возвращает: ничего не возвращает
*----------------------------------------------------------------------------------------
	LOCAL _laError[1]
    AERROR(_laError)
    * сообщение пользователю
    MESSAGEBOX(IIF(EMPTY(_lcTextMessage),"", _lcTextMessage + CHR(13));
               + "Номер ошибки:  " + ALLTRIM(STR(_laError[1])) + CHR(13);
               + "Текст ошибки:   " + _laError[3] + CHR(13) ;
               + "Модуль:              " + _laError[4], 16, "Внимание!")
ENDPROC
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Хранение изображения
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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