|
|
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Есть такая задача - БД на Postgresql и Qt-программа. Необходимо, чтобы при появлении новой записи в таблице БД оповещение об этом приходило на Qt-программу, которая считает эту запись. Каким образом это можно реализовать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2014, 14:02:30 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Marina.M, А может наоборот - программа будет периодически по таймеру просматривать таблицу на предмет наличия присутствия новой записи ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2014, 14:16:19 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2014, 14:19:59 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
V&NMarina.M, NOTIFY , LISTEN , UNLISTEN Ога. Однако, там были проблемы с уведомлением самого себя о внесенных самим собой изменениях. То есть: 1. Программа А сделала апдейт строки 2. Сервер проапдейтил строку. 3. Сервер отправил нотификацию. 4. Программа А не получила нотификацию. ТС, проверь этот момент хорошо, может быть, уже исправили. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2014, 14:29:16 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
ТриггерманMarina.M, А может наоборот - программа будет периодически по таймеру просматривать таблицу на предмет наличия присутствия новой записи ? это легко, но не подходит ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2014, 16:10:39 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2014, 16:29:47 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Классическое решение - использование очереди сообщений. При изменении данных в таблице сообщение об этом помещается в очередь сообщений, и в дальнейшем асинхронно читается клиентом. В простых случаях хватает NOTIFY, LISTEN, UNLISTEN, как уже говорили. Можно поглядеть на PgQ из Skytools или, если вся архитектура информационной системы завязана на очереди сообщений, выбрать срециалтзтрованные решения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.08.2014, 18:44:04 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Sergei.AgalakovКлассическое решение - использование очереди сообщений. При изменении данных в таблице сообщение об этом помещается в очередь сообщений, и в дальнейшем асинхронно читается клиентом. В простых случаях хватает NOTIFY, LISTEN, UNLISTEN, как уже говорили. Можно поглядеть на PgQ из Skytools или, если вся архитектура информационной системы завязана на очереди сообщений, выбрать срециалтзтрованные решения. спасибо. идеально для решения подошел пример из вот этой ссылки http://www.prog.org.ru/index.php?topic=25053.msg178942 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.08.2014, 13:41:26 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Возник еще один вопрос по поводу получения оповещений из базы данных в проекте на Qt. Например, приходит оповещение по update. Но проблема в том, что мы не знаем по какой строке произошло изменение. На одном из форумов написано, что есть два варианта решения этой задачи - штампы времени изменения в таблице или создавать еще одну дополнительную таблицу, куда добавлять строки в какой таблице произошло изменение и что изменилось. Ссылка на этот форум: http://www.forum.crossplatform.ru/index.php?showtopic=9176 Действительно ли только таким образом можно решить эту проблему или есть более простые решения получить номер записи, где произошло изменение? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2014, 10:10:29 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Marina.M, если версия postgresql >= 9.0, то notify/listen умеют передавать и принимать дополнительное текстовое поле (payload). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.08.2014, 10:37:04 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
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 как то так... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2014, 22:38:38 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Marina.M, Забыл малость, подписка на сообщения: // subscribe to a channel broadcasting between stations oConn:Listen( "notify_"+oConn:cDataBase ) // команда серверу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.08.2014, 22:45:07 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
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 по оповещению из базы данных. Если можно, то приведите пример. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2014, 10:55:28 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Marina.Mа можно подробнее? Попытки найти информацию в поисковиках ничего не дали. http://www.postgresql.org/docs/current/static/sql-notify.html Marina.MМожем ли мы созданным правилом передать payload(строка, где произошло изменение)? Или это надо делать с помощью триггера? можете, через функцию pg_notify . пример: Код: plsql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2014, 15:41:59 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
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'. Следующее...а Вы можете в правило параметр передать? Вот поподробнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2014, 16:06:22 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
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 " ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.09.2014, 16:19:05 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Всё это замечательно. Но хочется понять есть ли возможность применять в этом случае 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, если это возможно. Если нет, то разбираться уже по другим средствам. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2014, 10:46:33 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
Marina.M, Разбор: notification(const QString&) равно команде на сервере NOTIFY имя_канала надо: notification(const QString&) равно команде на сервере NOTIFY имя_канала, 'то что мы передаем' то есть: connect(db.driver(),SIGNAL(notification(const QString&)),SLOT(функция-обработчик())); в QString должно быть: QString& ===>>>> " update_table, 'то что мы передаем' " а это, как я понимаю, переменная, а не const, потому что 'то что мы передаем' будет меняться. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2014, 11:20:31 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
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 - это имя поля таблицы, содержащее строчку в таблице ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2014, 13:58:41 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2014, 14:26:22 |
|
||
|
как при появлении новой записи в БД оповестить об этом внешнюю программу?
|
|||
|---|---|---|---|
|
#18+
buddy_ekb, проект в qt 4.8.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2014, 14:30:42 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=38733887&tid=1998508]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
173ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
| others: | 194ms |
| total: | 466ms |

| 0 / 0 |
