等待sqlalchemy的行更新或行插入

时间:2014-06-18 12:25:35

标签: python postgresql sqlalchemy

我有一个应用程序,它显示每5-10分钟更新一次的数据库的内容。加载数据库中的所有数据大约需要5分钟。我不想在每次刷新时重新加载数据库中的所有数据,而是只加载已更新的新行或行字段。

  1. 是否可以使用sqlalchemy检查更改的字段或新字段(以轮询更改)?
  2. 是否可以使用sqlalchemy等待更改或新字段(带阻塞函数调用)?
  3. 如果重要的话,数据库是一个postgres数据库。

2 个答案:

答案 0 :(得分:3)

ProstgeSQL有一个NOTIFY / LISTEN机制,可以与触发器一起发送插入,删除和更新通知。通知包括一个参数,例如表和操作。

它看起来不像SQLAlchemy支持这个功能,可能因为它不是SQL标准而是Postgres特有的。

以下是使用python和twisted http://www.divillo.com/

检查带有NOTIFY / LISTEN的prostgres数据库中的更改的示例

免责声明,我刚刚浏览了sqlalchemy和postgres的文档。在postgres和python中使用NOTIFY进行更多Google搜索可能会提供更多帮助。

答案 1 :(得分:0)

SQLAlchemy不直接支持Postgres LISTEN / NOTIFY,但是您可以通过psycopg2来获得它,然后它将为您提供这种功能:http://initd.org/psycopg/docs/advanced.html#async-notify

(我是从https://gist.github.com/dtheodor/3862093af36a1aeb8104出发的)

Psycopg2可以进行通知的完全异步传递。我个人在SQLAlchemy内部对此没有多大运气,我怀疑这对他们来说太低了,无法支持。但是,文档下面有一个复制的示例,该示例使用select()等待连接说某事正在发生,然后在其上使用poll()来查看是否有通知。

import select
import psycopg2
import psycopg2.extensions

conn = psycopg2.connect(DSN)
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)

curs = conn.cursor()
curs.execute("LISTEN test;")

print "Waiting for notifications on channel 'test'"
while 1:
    if select.select([conn],[],[],5) == ([],[],[]):
        print "Timeout"
    else:
        conn.poll()
        while conn.notifies:
            notify = conn.notifies.pop(0)
            print "Got NOTIFY:", notify.pid, notify.channel, notify.payload

此示例具有可选的5秒超时,但是有时该超时非常方便,可以同时检查其他内容。

一个这样的用例是当您使用NOTIFY告诉您表正在更新时。您将超时设置为相当长的时间。如果收到通知或超时,请执行SELECT来查看表中的更改。这样,如果您收到NOTIFY通知,便会立即进行操作,但是即使您未收到通知,最终还是会这样做。