Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
Добрый день, коллеги.

Изучаю libpq c

В этом я полнейший чайник :(

Но есть желание.

В теме будут вопросы, иногда совсем простые.




Очень надеюсь на помощь Maxim Boguk, mefman и других светлых умов форума.
14 янв 22, 17:52    [22421243]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
Вопрос №1



Как вывести результат PQresultStatus(res) на экран?



Так выводит не статус, а :


        fprintf(stderr,"PQresultStatus: %s", PQresultStatus(res));


Segmentation fault




Кусок текста полностью, на котором останавливается:

    res = PQexec(conn, "SELECT version();");


        fprintf(stderr,"PQresultStatus: %s", PQresultStatus(res));

    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr, "PQexec command failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }


Я подозреваю что тут вместо PGRES_COMMAND_OK выдает PGRES_TUPLES_OK


Но хочется вывести что он выводит, подозреваю какое-то преобразование требуется.
14 янв 22, 18:00    [22421247]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
PGRES_COMMAND_OK выдает PGRES_TUPLES_OK

так и было, но как вывести на экран текущую PQresultStatus так не разобрался пока.
14 янв 22, 18:17    [22421253]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
grgdvo
Member

Откуда:
Сообщений: 144
Уткъ,

printf("...%s\n", PQresStatus(PQresultStatus(res)));
14 янв 22, 19:24    [22421281]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
grgdvo
Уткъ,

printf("...%s\n", PQresStatus(PQresultStatus(res)));



Большое спасибо!

...PGRES_TUPLES_OK


Почитаю про разницу между printf и fprintf.





Вопрос №1 снят.
14 янв 22, 20:00    [22421296]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
Вопрос №2


Как взять один столбец таблицы на одном сервере и вставить эти данные в новую таблицу на другом?


Я так понимаю что требуется PQputCopyData.

Но как в нее вставить результат запроса с другого сервера?
16 янв 22, 03:58    [22421760]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
grgdvo
Member

Откуда:
Сообщений: 144
Уткъ,

Советую сначала представить задачу на SQL уровне, что вы хотите, а потому уже переложить на libpq.
PG не колоночная СУБД, и просто так взять одну колонку и куда-то там ее вставить не получится.
И PQputCopyData здесь точно не поможет (эта функция реализует SQL-команду COPY).
16 янв 22, 10:36    [22421782]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
grgdvo
Уткъ,

Советую сначала представить задачу на SQL уровне, что вы хотите, а потому уже переложить на libpq.
PG не колоночная СУБД, и просто так взять одну колонку и куда-то там ее вставить не получится.
И PQputCopyData здесь точно не поможет (эта функция реализует SQL-команду COPY).



Да, я давно все представил требуется:

INSERT INTO table
SELECT field1 FROM dblink


Как это сделать?

Я думал на PQputCopyData результат запроса как-то подавать.
16 янв 22, 12:47    [22421795]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
сразу говорю что сам длинк не подходит.
16 янв 22, 12:48    [22421797]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 55283
Получаешь данные с одного сервера запросом SELECT, потом вставляешь их в другой запросом INSERT.
16 янв 22, 14:38    [22421823]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Maxim Boguk
Member

Откуда: По разному.
Сообщений: 5087
Dimitry Sibiryakov
Получаешь данные с одного сервера запросом SELECT, потом вставляешь их в другой запросом INSERT.


Зачем писать свой FDW если нет каких то КРАЙНЕ специфических требований - я не знаю.

PS: FDW который множественные вставки через insert делает - для batch переносов пригоден крайне плохо потому что упирается не в скорость серверов и даже не в ширину канала а в network latency которая почти никак не поддаётся снижению обычно.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
16 янв 22, 17:27    [22421851]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
Maxim Boguk
Dimitry Sibiryakov
Получаешь данные с одного сервера запросом SELECT, потом вставляешь их в другой запросом INSERT.


Зачем писать свой FDW если нет каких то КРАЙНЕ специфических требований - я не знаю.

PS: FDW который множественные вставки через insert делает - для batch переносов пригоден крайне плохо потому что упирается не в скорость серверов и даже не в ширину канала а в network latency которая почти никак не поддаётся снижению обычно.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru


да, инсерт тут не в тему как-то.

copy (PQputCopyData) подходит больше в теории


но как это сделать?

я так понял что как-то надо на вход подать PQputCopyData результат SELECT с другого сервера.


но примеров таких не нашел еще...
16 янв 22, 18:49    [22421877]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
grgdvo
Member

Откуда:
Сообщений: 144
Уткъ,

Надо определится, что конкретно Вы хотите.
Вопрос №2 звучал как, хочу взять колонку таблицы с одного сервера и вставить ее в таблицу другого.
Покажите источники данных... на пальцах, скринами... как-нибудь покажите.

(Ответ при прямом прочтении вопроса - колонку данных вставить нельзя, можно вставить(изменить/удалить) список записей, состоящих из полей и как бы образующих колонки).
16 янв 22, 19:47    [22421902]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
grgdvo
Уткъ,

Надо определится, что конкретно Вы хотите.
Вопрос №2 звучал как, хочу взять колонку таблицы с одного сервера и вставить ее в таблицу другого.
Покажите источники данных... на пальцах, скринами... как-нибудь покажите.

(Ответ при прямом прочтении вопроса - колонку данных вставить нельзя, можно вставить(изменить/удалить) список записей, состоящих из полей и как бы образующих колонки).


яж писал:

INSERT INTO table
SELECT field1 FROM dblink



поясняю:

взять результат SELECT field1 FROM table1 на одном сервере и вставить его в таблицу на другом сервере.

вроде понятно цель описал.

Как это сделать?
16 янв 22, 20:36    [22421910]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
grgdvo,

вот картинка

К сообщению приложен файл. Размер - 57Kb
16 янв 22, 20:52    [22421915]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
Ну или как-то PQgetCopyData с одного сервера в PQputCopyData перенаправить?
16 янв 22, 22:45    [22421945]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
mefman
Member

Откуда:
Сообщений: 3758
Уткъ,
По-моему, Вы занимаетесь ерундой.
17 янв 22, 00:01    [22421961]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Уткъ
Member

Откуда:
Сообщений: 295
mefman
Уткъ,
По-моему, Вы занимаетесь ерундой.


Возможно, однако надо сделать это.

Вы можете подсказать как?
17 янв 22, 01:15    [22421969]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Melkij
Member

Откуда: Санкт-Петербург
Сообщений: 1427
Уткъ
grgdvo,

вот картинка

psql -h host1 -c 'copy tablename(columnname) to stdout' | psql -h host2 -c 'copy tablename from stdin'
всё
17 янв 22, 10:53    [22422060]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Misha111
Member

Откуда:
Сообщений: 93
Уткъ,

через дблинк обычным инсертом
17 янв 22, 10:55    [22422063]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 55283
Maxim Boguk
FDW который множественные вставки через insert делает - для batch переносов пригоден крайне плохо потому что упирается не в скорость серверов и даже не в ширину канала а в network latency которая почти никак не поддаётся снижению обычно.

Снижению да, но поддаётся маскированию за счёт буферизации fetch на одной стороне и Array DML/Bulk Insert/etc на другой в результате чего по сети идёт поток данных без ожидания ответа на каждую запись.

PS: Чем, собственно, и занимаются PQgetCopyData/PQputCopyData если документация не врёт.

Сообщение было отредактировано: 17 янв 22, 15:09
17 янв 22, 15:05    [22422211]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
grgdvo
Member

Откуда:
Сообщений: 144
Уткъ
mefman
Уткъ,
По-моему, Вы занимаетесь ерундой.


Возможно, однако надо сделать это.

Вы можете подсказать как?


Если делать в лоб без dblink и прочих плюшек, то примерно как-то так

/* select ... from ... -- db1 */
PGconn* from_db = PQconnectdb("host=db1 ...");
PGresult* from_data = PQexec(from_db, "SELECT from_mycolumn FROM from_mytable");

/* for_insert - это строка текста, которую прибавим к запросу 
INSERT INTO to_mytable VALUES <здесь список значений в скобках> (xxx), (yyy) ...
*/
char* to_insert_values = 0;

for (i; i < PQntuples(from_data); i++)
{
  char* from_column_val = PQgetvalue(from_data, i, 0);
  /* здесь надо копировать from_column_val в отдельную строку для последующего INSERT; выделять промеж. память под эти значения */
  ... strcat(to_insert_values, from_column_val);
}
/* Вычерпали все записи, скопировали значения, можно закрыть соединение from */
PQclear(from_data);
PQfinish(from_db);

char* to_query = 0;
malloc(??? посчитать сколько примерно надо памяти для строки INSERT запроса);

strcat(to_query, to_insert_values);
/* Здесь в to_query должны получить строку вида "INSERT INTO to_mytable (to_mycolumn) VALUES (xyz), (abc), ...
где последняя часть сгенерирована в цикле при получении значений с db1 */

PGconn* to_db = PQconnectdb("host=db2 ...");
PGresult* to_data = PQexec(to_db, to_query);
PQclear(to_data);
PQfinish(to_db);

return 0;
18 янв 22, 22:41    [22422879]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
Melkij
Member

Откуда: Санкт-Петербург
Сообщений: 1427
grgdvo,

а зачем так сложно? Открыли два коннекта, в одном сделали copy from в другом copy to и просто перекладываете построчно всё из первого во второй без всяких извращений вокруг форматирования insert'ов.
Это если уж очень хочется на C делать.
19 янв 22, 10:30    [22422994]     Ответить | Цитировать Сообщить модератору
 Re: Изучаю libpq c . Чтобы не плодить темы, создал эту.  [new]
grgdvo
Member

Откуда:
Сообщений: 144
Melkij,

автор
Если делать в лоб без dblink и прочих плюшек, то примерно как-то так

Это пусть уж ТС решает, как ему проще или сложнее.
Захочет - спросит.
Предела совершенства нет.
19 янв 22, 21:34    [22423433]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить