diff --git a/articles.xml b/articles.xml index 815a735c..cd98cdcb 100644 --- a/articles.xml +++ b/articles.xml @@ -3366,62 +3366,56 @@ but if there is anything to point out I'd be happy to know. Best option would be <li><a class="reference external" href="https://pypi.org/packages/source/p/psycopg2/psycopg2-2.3.1.tar.gz.asc">Psycopg 2.3.1 signature</a></li> </ul> <p>Cheers!</p> -Psycopg 2.3.0 released2010-12-01T00:00:00ZFederico Di Gregoriourn:uuid:12f1b527-a80a-34f4-9c06-c281d38f0559<p>Hi *,</p> -<p>lately my involvement on psycopg has been quite small (work and other -projects are taking their toll) but thanks to Daniele (with some help -from Jan) here is a new psycopg2 release. The number of changes is big -(an excerpt from the NEWS file is at the end, as always) so we decided -to bump up the version to 2.3.0 and to test, and test... and test. We -tested this new release on Linux and Windows, with Python 2.4, 2.5, 2.6, -2.7 and on PostgreSQL from 7.4 to 9.0.</p> +PostgreSQL notifications with Psycopg2 and Eventlet2010-12-01T00:00:00ZDaniele Varrazzourn:uuid:85a44537-7b4f-3e10-9273-1a2b12fb4757<p>PostgreSQL supports <a class="reference external" href="https://www.postgresql.org/docs/9.0/interactive/sql-notify.html">asynchronous notifications</a>, a simple messaging system allowing clients to be notified about events occurred in the database. Notifications can be sent by any session using a &quot;<tt class="docutils literal">NOTIFY</tt> <em>channel</em>&quot; command and will be received by any session which has subscribed with a <tt class="docutils literal">LISTEN</tt> <em>channel</em> to receive updates. The system has been greatly improved in PostgreSQL 9.0 with the addition of a <em>message payload</em>, making the feature even more useful. Previously a typical use case would have been to notify interested sessions that a certain table was updated: now it is possible to signal for instance <em>which record</em> was changed. You can put the <tt class="docutils literal">NOTIFY</tt> command in a database trigger for automatic notifications on insert or update... the possibilities are actually quite interesting.</p> <!-- CUT-HERE --> -<p>As always, signed download from:</p> -<ul class="simple"> -<li><a class="reference external" href="https://pypi.org/packages/source/p/psycopg2/psycopg2-2.3.0.tar.gz">https://pypi.org/packages/source/p/psycopg2/psycopg2-2.3.0.tar.gz</a></li> -<li><a class="reference external" href="https://pypi.org/packages/source/p/psycopg2/psycopg2-2.3.0.tar.gz.asc">https://pypi.org/packages/source/p/psycopg2/psycopg2-2.3.0.tar.gz.asc</a></li> -</ul> -<p>Have fun, -federico</p> -<p>And here are the NEWS:</p> -<p>psycopg 2.3 aims to expose some new features introduced in PostgreSQL 9.0.</p> -<div class="section" id="main-new-features"> -<h2>Main new features</h2> -<ul class="simple"> -<li><tt class="docutils literal">dict</tt> to <tt class="docutils literal">hstore</tt> adapter and <tt class="docutils literal">hstore</tt> to <tt class="docutils literal">dict</tt> typecaster, using -both 9.0 and pre-9.0 syntax.</li> -<li>Two-phase commit protocol support as per DBAPI specification.</li> -<li>Support for payload in notifications received from the backed.</li> -<li><tt class="docutils literal">namedtuple</tt>-returning cursor.</li> -<li>Query execution cancel.</li> -</ul> -</div> -<div class="section" id="other-features-and-changes"> -<h2>Other features and changes</h2> -<ul class="simple"> -<li>Dropped support for protocol 2: Psycopg 2.3 can only connect to -PostgreSQL servers with version at least 7.4.</li> -<li>Don't issue a query at every connection to detect the client -encoding and to set the datestyle to ISO if it is already -compatible with what expected.</li> -<li><tt class="docutils literal">mogrify()</tt> now supports unicode queries.</li> -<li>Subclasses of a type that can be adapted are adapted as the -superclass.</li> -<li><tt class="docutils literal">errorcodes</tt> knows a couple of new codes introduced in PostgreSQL -9.0.</li> -<li>Dropped deprecated Psycopg &quot;own quoting&quot;.</li> -<li>Never issue a ROLLBACK on close/GC. This behaviour was introduced -as a bug in release 2.2, but trying to send a command while being -destroyed has been considered not safe.</li> -</ul> -</div> -<div class="section" id="bug-fixes"> -<h2>Bug fixes</h2> -<ul class="simple"> -<li>Fixed use of <tt class="docutils literal">PQfreemem</tt> instead of <tt class="docutils literal">free</tt> in binary typecaster.</li> -<li>Fixed access to freed memory in <tt class="docutils literal">conn_get_isolation_level()</tt>.</li> -<li>Fixed crash during Decimal adaptation with a few 2.5.x Python -versions (<a class="reference external" href="https://psycopg.lighthouseapp.com/projects/62710/tickets/7">ticket #7</a>).</li> -<li>Fixed notices order (<a class="reference external" href="https://psycopg.lighthouseapp.com/projects/62710/tickets/9">ticket #9</a>).</li> -</ul> +<p>Psycopg2 allows a client program to <a class="reference external" href="/docs/advanced.html#asynchronous-notifications">receive notifications from the database backend</a>. Starting from version 2.3 the notification received will also include the payload, when connected to a PostgreSQL 9.0 server. The notification are received automatically after each query and are made available in the <a class="reference external" href=":/docs/connection.html#connection.notifies"><tt class="docutils literal">notifies</tt></a> attribute of the connection. They are also received using the <a class="reference external" href="/docs/connection.html#connection.poll"><tt class="docutils literal">poll()</tt></a> method, without the need of issuing queries only to receive notifications.</p> +<p>But polling a connection is not the most efficient nor timely way to receive notifications: a better approach is to ask the OS to wake us up when there is something to read on the connection socket. This approach is particularly appealing when using an event-driven framework such as <a class="reference external" href="https://twistedmatrix.com/">Twisted</a> or <a class="reference external" href="https://eventlet.net/">Eventlet</a>, with which is easy to perform other tasks while there is nothing to read on the connection. In &quot;regular&quot; Python programs it is possible to use <tt class="docutils literal">select()</tt> to block until a notification arrives (see the documentation for an example): this would block the entire program. If some concurrency is required it is possible to use the blocking syscall in a thread to allow the rest of the program to carry on.</p> +<div class="section" id="eventlet-example"> +<h2>Eventlet example</h2> +<p>This example shows how hook the notifications system into Eventlet: using it with a <a class="reference external" href="https://en.wikipedia.org/wiki/WebSockets">WebSocket</a> it is possible to send an event from the database to the application and up to a web browser, all in push mode! The example requires PostgreSQL 9.0 and Psycopg 2.3 as it uses notification payloads.</p> +<p>This function handles a WebSocket connection in a green thread: it creates a <tt class="docutils literal">Queue</tt> and opens a database connection (calling the <tt class="docutils literal">dblisten()</tt> function), then blocks on the queue waiting to receive notifications: as soon as any is received, its payload is forwarded to the browser. This is obviously just an example: a database connection for every browser wouldn't scale very much...</p> +<pre class="code python literal-block"> +<span class="kn">import</span> <span class="nn">eventlet</span><span class="w"> +</span><span class="kn">from</span> <span class="nn">eventlet</span> <span class="kn">import</span> <span class="n">wsgi</span><span class="w"> +</span><span class="kn">from</span> <span class="nn">eventlet</span> <span class="kn">import</span> <span class="n">websocket</span><span class="w"> + +</span><span class="nd">&#64;websocket</span><span class="o">.</span><span class="n">WebSocketWSGI</span><span class="w"> +</span><span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="n">ws</span><span class="p">):</span><span class="w"> + </span><span class="sd">&quot;&quot;&quot; + Receive a connection and send it database notifications. + &quot;&quot;&quot;</span><span class="w"> +</span> <span class="n">q</span> <span class="o">=</span> <span class="n">eventlet</span><span class="o">.</span><span class="n">Queue</span><span class="p">()</span><span class="w"> +</span> <span class="n">eventlet</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="n">dblisten</span><span class="p">,</span> <span class="n">q</span><span class="p">)</span><span class="w"> +</span> <span class="k">while</span> <span class="mi">1</span><span class="p">:</span><span class="w"> +</span> <span class="n">n</span> <span class="o">=</span> <span class="n">q</span><span class="o">.</span><span class="n">get</span><span class="p">()</span><span class="w"> +</span> <span class="nb">print</span> <span class="n">n</span><span class="w"> +</span> <span class="n">ws</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">n</span><span class="o">.</span><span class="n">payload</span><span class="p">)</span> +</pre> +<p>When <tt class="docutils literal">handle()</tt> blocks on the queue the control of the program switches to a different green thread, allowing the rest of the program to keep on running even if single-threaded.</p> +<p>The <tt class="docutils literal">dblisten</tt> function sets up the listening database connection:</p> +<pre class="code python literal-block"> +<span class="kn">import</span> <span class="nn">psycopg2</span><span class="w"> +</span><span class="kn">from</span> <span class="nn">psycopg2.extensions</span> <span class="kn">import</span> <span class="n">ISOLATION_LEVEL_AUTOCOMMIT</span><span class="w"> +</span><span class="kn">from</span> <span class="nn">eventlet.hubs</span> <span class="kn">import</span> <span class="n">trampoline</span><span class="w"> + +</span><span class="k">def</span> <span class="nf">dblisten</span><span class="p">(</span><span class="n">q</span><span class="p">):</span><span class="w"> + </span><span class="sd">&quot;&quot;&quot; + Open a db connection and add notifications to *q*. + &quot;&quot;&quot;</span><span class="w"> +</span> <span class="n">cnn</span> <span class="o">=</span> <span class="n">psycopg2</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">dsn</span><span class="p">)</span><span class="w"> +</span> <span class="n">cnn</span><span class="o">.</span><span class="n">set_isolation_level</span><span class="p">(</span><span class="n">ISOLATION_LEVEL_AUTOCOMMIT</span><span class="p">)</span><span class="w"> +</span> <span class="n">cur</span> <span class="o">=</span> <span class="n">cnn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span><span class="w"> +</span> <span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&quot;LISTEN data;&quot;</span><span class="p">)</span><span class="w"> +</span> <span class="k">while</span> <span class="mi">1</span><span class="p">:</span><span class="w"> +</span> <span class="n">trampoline</span><span class="p">(</span><span class="n">cnn</span><span class="p">,</span> <span class="n">read</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="w"> +</span> <span class="n">cnn</span><span class="o">.</span><span class="n">poll</span><span class="p">()</span><span class="w"> +</span> <span class="k">while</span> <span class="n">cnn</span><span class="o">.</span><span class="n">notifies</span><span class="p">:</span><span class="w"> +</span> <span class="n">n</span> <span class="o">=</span> <span class="n">cnn</span><span class="o">.</span><span class="n">notifies</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span><span class="w"> +</span> <span class="n">q</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> +</pre> +<p>The connection is set in <a class="reference external" href="/docs/usage.html#transactions-control">autocommit mode</a>, otherwise the notification would be postponed until the end of the transaction. The <em>trampoline</em> is the Eventlet function that schedules a green thread switch: we ask it to return us the control when the file descriptor underlying the connection will have something to read. Once the system wakes up again we use <tt class="docutils literal">poll()</tt> to parse eventual notifications received, that will be added to the queue and thus passed to the client.</p> +<p>The rest of the example is not shown here: it only consists in a static page and the web server setup. You can <a class="reference external" href="pushdemo.py">download the complete example</a>.</p> +<p>Running the program and opening the page <a class="reference external" href="http://localhost:7000/">http://localhost:7000/</a> in a WebSocket-enabled browser you will see a page with three coloured bars: using a command such as <tt class="docutils literal">NOTIFY data, 'green'</tt> in a psql shell, one of the bars in the page will be updated accordingly. Here is a screenshot:</p> +<img alt="psycopg eventlet push demo" class="align-center" src="pushdemo.png" style="width: 477px; height: 327px;" /> </div> \ No newline at end of file diff --git a/docs/_static/documentation_options.js b/docs/_static/documentation_options.js index 0779a00a..c33771f6 100644 --- a/docs/_static/documentation_options.js +++ b/docs/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '2.9.10.dev1', + VERSION: '2.9.10', LANGUAGE: 'en', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/advanced.html b/docs/advanced.html index 31b80d5b..0185763e 100644 --- a/docs/advanced.html +++ b/docs/advanced.html @@ -6,7 +6,7 @@ - More advanced topics — Psycopg 2.9.10.dev1 documentation + More advanced topics — Psycopg 2.9.10 documentation @@ -27,7 +27,7 @@