powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / как при появлении новой записи в БД оповестить об этом внешнюю программу?
22 сообщений из 22, страница 1 из 1
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38713048
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть такая задача - БД на Postgresql и Qt-программа. Необходимо, чтобы при появлении новой записи в таблице БД оповещение об этом приходило на Qt-программу, которая считает эту запись. Каким образом это можно реализовать?
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38713068
Триггерман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Marina.M,

А может наоборот - программа будет периодически по таймеру просматривать таблицу на предмет наличия присутствия новой записи ?
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38713072
V&N
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
V&N
Гость
Marina.M,
NOTIFY , LISTEN , UNLISTEN
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38713081
rovan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
V&NMarina.M,
NOTIFY , LISTEN , UNLISTEN
Ога. Однако, там были проблемы с уведомлением самого себя о внесенных самим собой изменениях.
То есть:
1. Программа А сделала апдейт строки
2. Сервер проапдейтил строку.
3. Сервер отправил нотификацию.
4. Программа А не получила нотификацию.

ТС, проверь этот момент хорошо, может быть, уже исправили.
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38713246
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ТриггерманMarina.M,

А может наоборот - программа будет периодически по таймеру просматривать таблицу на предмет наличия присутствия новой записи ?

это легко, но не подходит
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38713281
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
V&NMarina.M,
NOTIFY , LISTEN , UNLISTEN

Спасибо. Посмотрю
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38713404
Sergei.Agalakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Классическое решение - использование очереди сообщений. При изменении данных в таблице сообщение об этом помещается в очередь сообщений, и в дальнейшем асинхронно читается клиентом.
В простых случаях хватает NOTIFY, LISTEN, UNLISTEN, как уже говорили. Можно поглядеть на PgQ из Skytools или, если вся архитектура информационной системы завязана на очереди сообщений, выбрать срециалтзтрованные решения.
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38714091
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sergei.AgalakovКлассическое решение - использование очереди сообщений. При изменении данных в таблице сообщение об этом помещается в очередь сообщений, и в дальнейшем асинхронно читается клиентом.
В простых случаях хватает NOTIFY, LISTEN, UNLISTEN, как уже говорили. Можно поглядеть на PgQ из Skytools или, если вся архитектура информационной системы завязана на очереди сообщений, выбрать срециалтзтрованные решения.

спасибо. идеально для решения подошел пример из вот этой ссылки http://www.prog.org.ru/index.php?topic=25053.msg178942
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38732394
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возник еще один вопрос по поводу получения оповещений из базы данных в проекте на Qt.

Например, приходит оповещение по update. Но проблема в том, что мы не знаем по какой строке произошло изменение. На одном из форумов написано, что есть два варианта решения этой задачи - штампы времени изменения в таблице или создавать еще одну дополнительную таблицу, куда добавлять строки в какой таблице произошло изменение и что изменилось.

Ссылка на этот форум: http://www.forum.crossplatform.ru/index.php?showtopic=9176

Действительно ли только таким образом можно решить эту проблему или есть более простые решения получить номер записи, где произошло изменение?
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38732412
buddy_ekb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Marina.M,

если версия postgresql >= 9.0, то notify/listen умеют передавать и принимать дополнительное текстовое поле (payload).
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38733714
Mavr747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Marina.M, Конкретно на xBase++ (просто пишу на нем)
----------------
// Get server notify if exist (этот участок крутится в петле)
If PQconsumeInput(oConn:pDB) = 1 // функция из libpg.dll
If ((notify := PQnotifies(oConn:pDB)) != 0) // функция из libpg.dll
oInfo := pgNotify():new()
oInfo:_link_(notify,.F.)
ExecuteNotify( oDialog:oCurBrowser, oInfo ) // Смотрим далее...
PQfreeNotify(notify)
nNotifies++
oInfo := NIL
EndIf
EndIf
-----------------
FUNCTION ExecuteNotify( browser, oNotify )
local cLine, cTable, i, aFindRec, nOldRec, nRec, nHwnd
local cMessage := oNotify:cExtra
local cChannel := oNotify:cRelName
local nPid := oNotify:be_pid // а это process id
..... далее в коде ..... ExecuteNotify .....
// Is other station send notify?
If nPid <> browser:table:oPG:backendPID
а при создании oPG...[ ::backendPID := PQbackendPID( ::pDB )] // функция из libpg.dll

Посылка из другого клиентского приложения всем кто слушает
::table:oPG:SendNotify(::table:cTable+":APPEND RECORD") // посылаю имя таблицы и текст что случилось

METHOD XBPgSql:SendNotify( cNotify ) // Реализация метода посылки
local res
If !Empty(::notifyChannel)
res := PQexec( ::pDB, "NOTIFY " + ::notifyChannel + ", '"+cNotify+"'" ) // функция из libpg.dll


как то так...
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38733716
Mavr747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Marina.M, Забыл малость, подписка на сообщения:
// subscribe to a channel broadcasting between stations
oConn:Listen( "notify_"+oConn:cDataBase ) // команда серверу.
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38733887
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
buddy_ekbMarina.M,

если версия postgresql >= 9.0, то notify/listen умеют передавать и принимать дополнительное текстовое поле (payload).

а можно подробнее? Попытки найти информацию в поисковиках ничего не дали.

Я делала так:
в postgresql создавала правило:
CREATE RULE notify_some_table_update_rule AS ON UPDATE TO some_table DO NOTIFY some_table_updated;
а в Qt использовала функцию SubscribeToNotification("some_table_updated")

Можем ли мы созданным правилом передать payload(строка, где произошло изменение)? Или это надо делать с помощью триггера?
И как обработать полученное поле в проекте на Qt по оповещению из базы данных.

Если можно, то приведите пример.
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38734174
buddy_ekb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Marina.Mа можно подробнее? Попытки найти информацию в поисковиках ничего не дали.

http://www.postgresql.org/docs/current/static/sql-notify.html

Marina.MМожем ли мы созданным правилом передать payload(строка, где произошло изменение)? Или это надо делать с помощью триггера?
можете, через функцию pg_notify . пример:
Код: plsql
1.
CREATE RULE some_notify_rule AS ON UPDATE TO some_table DO SELECT pg_notify('some_channel', NEW.some_text);
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38734199
Mavr747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Marina.M,

Marina.M,
В документации Postgre:
Configure and execute a listen/notify sequence from psql:
LISTEN virtual; // Слушаем канал "virtual"
NOTIFY virtual; // Сообщаем в канал "virtual"

В моем случае вместо "virtual" имя базы данных т.е этот канал слушают только те, кто работает с базой с таким именем.
res := PQexec( ::pDB, "NOTIFY " + ::notifyChannel + ", '"+cNotify+"'" )
команда посланная станцией в канал (notifyChannel - property у класса), но может быть и просто переменная в которой имя канала (в моем случае имя базы данных с которой работает клиент). Через запятую тот самый параметр [текстовое поле (payload)]
в котором я передаю имя таблицы которая послала сообщение всем кто работает с данной базой + ":" + "действие которое сделано в таблице" ("APPEND RECORD" - вставили запись на какой-то станции, можно и номер записи передать тоже через ":". Почему двоеточие? ответ да хоть, что угодно, нам в принимающей стороне надо знать какой разделитель использован для имени таблицы (т.к. если мы с ней не работаем, то это сообщение не для нас и т.д)
PQbackendPID( ::pDB )] отдает Id процесса который сервер выделил для нашего соединения, (у каждого соединения он свой) зная его мы НЕ будем обрабатывать свои сообщения.
В петле где обрабатываются все сообщения (If PQconsumeInput(oConn:pDB) = 1 проверка если есть сообщение, взять указатель на него If ((notify := PQnotifies(oConn:pDB)) != 0) и далее если указатель не пустой....вытащить собственно сообщение и в своей процедуре сделать предписанные действия. Пришло APPEND RECORD, и если на моей станции user находится в Grid(е) в конце таблицы, то резонно показать, что появилась новая запись, если юзер не режиме редактирования поля, обновляю Grid
В Вашем случае ...DO NOTIFY some_table_updated, 'сообщение которое надо очевидно построить? оно то и есть payload'. Следующее...а Вы можете в правило параметр передать?
Вот поподробнее.
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38734214
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
buddy_ekb,

рулы, суть, -- деприкейтит.
лучше уж триггер тогда.

---

а, вообще, воот
http://habrahabr.ru/post/231563/
тут писал ( mtyurin, 4 августа 2014 в 13:15# ):

"
www.hagander.net/talks/
Data driven cache invalidation (slightly updated), JDCon-East, New York City, NY, March 2011 and EuroPython 2011, Florence, Italy (+ scripts)

че-то правда у него пдфка не грузится, а
скрипты скачиваются

вот еще видео
ep2013.europython.eu/conference/talks/data-driven-cache-invalidation

суть в PGQ
"
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38734661
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всё это замечательно. Но хочется понять есть ли возможность применять в этом случае Qt.

Приведу алгоритм, как это реализовано сейчас в проекте Qt.

1. Создаю соединение с базой данных db.open()
2. Делаю подписку на оповещение по событию, например "update_table"
db.driver()->subscribeToNotification("update_table");
3. Соединяю сигнал notification(const QString&) с функцией обработчиком оповещения
connect(db.driver(),SIGNAL(notification(const QString&)),SLOT(функция-обработчик()));

Вот и хотелось бы кроме оповещение об изменении средствами Qt ловить и это дополнительное поле payload, если это возможно. Если нет, то разбираться уже по другим средствам.
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38734701
Mavr747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Marina.M,
Разбор:
notification(const QString&) равно команде на сервере NOTIFY имя_канала
надо:
notification(const QString&) равно команде на сервере NOTIFY имя_канала, 'то что мы передаем'
то есть:
connect(db.driver(),SIGNAL(notification(const QString&)),SLOT(функция-обработчик()));
в QString должно быть:
QString& ===>>>> " update_table, 'то что мы передаем' "
а это, как я понимаю, переменная, а не const, потому что 'то что мы передаем' будет меняться.
:)
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38734923
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mavr747Marina.M,
Разбор:
notification(const QString&) равно команде на сервере NOTIFY имя_канала
надо:
notification(const QString&) равно команде на сервере NOTIFY имя_канала, 'то что мы передаем'
то есть:
connect(db.driver(),SIGNAL(notification(const QString&)),SLOT(функция-обработчик()));
в QString должно быть:
QString& ===>>>> " update_table, 'то что мы передаем' "
а это, как я понимаю, переменная, а не const, потому что 'то что мы передаем' будет меняться.
:)

сигнал notification имеет вид void notification(const QString &name), если убрать const, то при исполнении ругается:
Object::connect: No such signal qPSQLDriver::notification(QString&)

получается правило создаю с передачей дополнительного поля :
CREATE RULE some_notify_rule AS ON UPDATE TO some_table DO SELECT pg_notify('update_table', 'NEW.some_text');

затем слотом получаю оповещение 'update_table', но не вытащить второй параметр.

еще вопрос в том, 'NEW.some_text' идет обязательно в кавычках, то есть как строка, а как туда записать переменную, например NEW.id? Где id - это имя поля таблицы, содержащее строчку в таблице
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38734960
buddy_ekb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Marina.Mсигнал notification имеет вид void notification(const QString &name), если убрать const, то при исполнении ругается:
Object::connect: No such signal qPSQLDriver::notification(QString&)
какая у вас версия Qt? есть мнение, что в 5.x это исправлено. ветку 4 потребуется патчить.
https://bugreports.qt-project.org/browse/QTBUG-13500

Marina.Mеще вопрос в том, 'NEW.some_text' идет обязательно в кавычках, то есть как строка, а как туда записать переменную, например NEW.id? Где id - это имя поля таблицы, содержащее строчку в таблице
можно без кавычек: достаточно, чтобы параметр был текстовым. для вашего случая, по-видимому, потребуется привести числовое значение к текстовому представлению:
Код: plsql
1.
CREATE RULE some_notify_rule AS ON UPDATE TO some_table DO SELECT pg_notify('update_table', NEW.id::text);
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38734965
Marina.M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
buddy_ekb,

проект в qt 4.8.4
...
Рейтинг: 0 / 0
как при появлении новой записи в БД оповестить об этом внешнюю программу?
    #38735365
Mavr747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Marina.M,

Ой! Если "шас" не сработает, то снова в школу....
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / как при появлении новой записи в БД оповестить об этом внешнюю программу?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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