等待使用sqlalchemy进行行更新或插入
我有一个应用程序,它会显示一个数据库的内容,这个数据库每5到10分钟更新一次。加载数据库里的所有数据大约需要5分钟。为了避免每次刷新都重新加载所有数据,我想只加载新增的行或者那些已经更新的行的字段。
- 请问用sqlalchemy能不能检查哪些字段发生了变化或者是新增的字段?(也就是定期查看变化)
- 用sqlalchemy能不能等待字段的变化或者新增字段?(通过一个阻塞的函数调用)
这个数据库是postgres数据库,如果这有影响的话。
2 个回答
SQLAlchemy并不直接支持Postgres的LISTEN/NOTIFY功能,但你可以通过psycopg2来实现这个功能,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来通知你某个表被更新时。你可以把超时时间设置得比较长。如果你收到NOTIFY或者超时了,就可以执行一个SELECT查询,看看表里有什么变化。这样的话,如果收到NOTIFY就能立刻处理,但即使没有收到通知,最终也会处理。
PostgreSQL有一个叫做NOTIFY和LISTEN的机制,可以和触发器一起使用,来发送插入、删除和更新的通知。这些通知会包含一些信息,比如表名和操作类型。
看起来SQLAlchemy不支持这个功能,可能是因为这不是SQL的标准功能,而是PostgreSQL特有的。
这里有一个使用Python检查PostgreSQL数据库变化的例子,利用了NOTIFY和LISTEN:PostgreSQL LISTEN/NOTIFY
在网上搜索NOTIFY in PostgreSQL and python
可能会找到更多帮助。