一个方便的python接口,用于postgres的监听和通知功能。

pgpubsub的Python项目详细描述


pgpubsub提供了对构建的event notification system的方便访问 进入PostgreSQL数据库这提供了一个类似的实时发布/订阅系统 给Redis中的那个

用法

首先,您需要建立连接:

import pgpubsub
pubsub = pgpubsub.connect(user='postgres', database='test')

pgpubsub.connect()函数接受的参数与 由psycopg2.connect()函数支持。

发送事件

要发送事件,请使用pubsub.notify()方法:

pubsub.notify('test_channel', 'some message')

接收事件

要接收事件,必须首先使用 publinsub.listen()方法:

pubsub.listen('test')

您可以多次调用pubsub.listen()从多个 频道:

pubsub.listen('chan1')
pubsub.listen('chan2')

请注意,频道名称必须是有效的SQL identifiers。引用 Postgres文档:

SQL identifiers and key words must begin with a letter (a-z, but also letters with diacritical marks and non-Latin letters) or an underscore (_). Subsequent characters in an identifier or key word can be letters, underscores, digits (0-9), or dollar signs ($).

警告

因为通道是sql标识符而不是字符串,所以它们不能是 psycopg2引用/转义的字符串可以。建一个通道是不安全的 来自不受信任的用户输入的名称。

不要这样做:

channel = 'events_' + username
pubsub.listen(channel)

如果你这样做了,那么你的整个数据库可能会被 用户名;删除表用户Mandatory XKCD

一旦您订阅了一个或多个频道,您可以选择接收 通过迭代pubsub.events()或重复调用 pubsub.get_event()方法。

发布子事件()

这是pubsub上事件流的生成器。它让你 循环查看事件,就像查看列表一样:

for e in pubsub.events():
    print e.payload

在幕后,pubsub正在屏蔽标准库的 select.select函数。您可以为 events()控制等待时如何处理超时 选择。选择:

  • select_timeout:等待select的秒数。在给出 起来再试一次。默认为5。

  • yield_超时:默认为false。如果设置为true,则pubsub.events() 每次进入选择超时秒后,在接收到 一个事件。这对于WebSockets之类的东西很有用 即使未收到新数据,也发送保留消息:

    for e in pubsub.events(yield_timeouts=True):
        if e is None:
            send_websocket_ping()
        else:
            send_websocket_message(e.payload)
    

pubsub.get_event()

此方法总是立即返回如果收到事件,它将 返回该事件如果没有收到任何事件,它将不返回任何事件

如果已收到多个事件并正在队列中等待,则 重复的get_event()调用将继续返回下一个事件,直到没有 任何左边都不返回:

>>> pubsub.listen('test')
>>> pubsub.get_event() # Nothing delivered yet, so returns None
>>> pubsub.notify('test', 'message 1')
>>> pubsub.notify('test', 'message 2')
>>> pubsub.get_event()
Notify(9425, 'test', 'message 1')
>>> pubsub.get_event()
Notify(9425, 'test', 'message 2')
>>> pubsub.get_event() # No more messages, so returns None

get event()方法用于集成到事件循环中,其中 阻塞pubsub.events()会导致问题。

取消订阅

如果要停止接收当前频道中的事件 订阅后,您可以调用pubsub.unlisten():

pubsub.unlisten('channel2')

事件对象

pubsub.events()和pubsub.get_event()返回的事件对象是 psycopg2的实例Notify class他们有三个可能很有趣 属性:

  • payload:包含实际消息的字符串。

  • 频道:事件发送到的频道的名称。

  • pid:postgres服务器上处理 发件人的连接。这有助于防止 发送和接收事件的程序:

    my_pid = pubsub.conn.get_backend_pid()
    pubsub.listen('echo')
    for e in pubsub.events():
        sender_pid = e.pid
        if sender_pid != my_pid:
            pubsub.notify('echo', e.payload)
    

问答

在线程之间传递pubsub对象是否安全?

没有

为什么使用动词'notify'和'listen'而不是'publish'和 “订阅”?

pgpubsub中的方法被设计成尽可能类似于实际的 postgres中的sql命令,它们是NOTIFYLISTEN。博士后也会 引用“通知事件”而不是“消息”,因此pgpubsub使用相同的 任期。

为什么没有回调样式的接口?

总有一天,如果有需求和一个合理的规格

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
由于测试失败,java testcontainers maven构建失败   java实现jacobi算法实现laplace方程   java中的多线程:如何在不等待所有线程使用ExecutorService完成任务的情况下终止所有线程的执行?   java Hello World不在Android Studio 3中工作   ubuntu Tomcat7的Java版本不正确   java Javafx内存泄漏   对于手动实现的Spring数据存储库方法,我应该使用Java8默认方法吗?   googleappengine中的java添加过滤查询   html当使用JSOUP库在Java中读取标签时,如何保留标签(如<br>、<ul>、<li>、<p>等)的含义?   编码为什么jasper生成的报告在Java中不显示西里尔语(保加利亚语)?   java有没有办法隐藏当前位置和jdk动作?   java找出编译原型文件的版本   有没有办法在运行时更改java方法的访问修饰符?   语法字符串。。。Java中的参数   java数组元素在添加其他元素时会相互覆盖   eclipse中的java GWT项目   java如何为spring rest模板请求将动态json属性名映射到jackson   java无法在Windows 10上找到特定的JDK   在xml字符串和java字符串之间提取正则表达式子字符串