Re: improving async support in psycopg

Jan Urbański <[email protected]> Tue, 23 Mar 2010 01:38:27 +0100
Newsgroups gmane.comp.python.db.psycopg.devel
Message-ID <[email protected]>
On 21/03/10 02:07, Jan Urbański wrote:
> Hi,
>
> I've recently got the need for a asynchronous Python driver for
> PostgreSQL and I started looking for alternatives.

So here's a first attempt, only only doc changes and tests added.

This is basically a trimmed down version of what Markus Demleitner wrote 
a couple of months ago - it's missing the query cancellation feature 
that I will try to implement after reading the libpq documentation some 
more.

I'll keep on working on exposing more async features of the C library 
and adding more unit tests (I've started another thread with the fix for 
the test suite for PG 9.0).

Cheers,
Jan

_______________________________________________
Psycopg mailing list
Psycopg-IAPFreCvJWPBWskQ1e/[email protected]
http://lists.initd.org/mailman/listinfo/psycopg
0002-Add-tests-and-fix-documentation-for-asynchronous-que.patch (text/x-diff, 3.8 KB)
From d545c7fe2cdf0fb2043f2573348dc8717413e810 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Urba=C5=84ski?= <[email protected]>
Date: Tue, 23 Mar 2010 01:07:36 +0100
Subject: [PATCH 2/2] Add tests and fix documentation for asynchronous queries support.

---
 doc/async.txt       |    8 +++---
 tests/__init__.py   |    2 +
 tests/test_async.py |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 tests/test_async.py

diff --git a/doc/async.txt b/doc/async.txt
index 518d5fe..be51c88 100644
--- a/doc/async.txt
+++ b/doc/async.txt
@@ -42,8 +42,8 @@ asynchronous queries:
       make possible to use a cursor in a context where a file object would be
       expected (like in a select() call.)
 
-    .isbusy()
-      Returns True if the backend is still processing the query or false if
+    .isready()
+      Returns False if the backend is still processing the query or True if
       data is ready to be fetched (by one of the .fetchXXX() methods.)
       
 A code snippet that shows how to use the cursor object in a select() call:
@@ -53,13 +53,13 @@ A code snippet that shows how to use the cursor object in a select() call:
         
     conn = psycopg.connect(database='test')
     curs = conn.cursor()
-    curs.execute("SEECT * from test WHERE fielda > %s", (1971,), async=1)
+    curs.execute("SELECT * from test WHERE fielda > %s", (1971,), async=1)
 
     # wait for input with a maximum timeout of 5 seconds
     query_ended = False
     while not query_ended:
         rread, rwrite, rspec = select([cursor, another_file], [], [], 5)
-	if not cursor.isbusy():
+	if cursor.isready():
 	   query_ended = True
 	# manage input from other sources like other_file, etc.
     print "Query Results:"
diff --git a/tests/__init__.py b/tests/__init__.py
index f8cda51..6c91014 100755
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -38,6 +38,7 @@ import test_transaction
 import types_basic
 import types_extras
 import test_lobject
+import test_async
 
 def test_suite():
     suite = unittest.TestSuite()
@@ -51,6 +52,7 @@ def test_suite():
     suite.addTest(types_basic.test_suite())
     suite.addTest(types_extras.test_suite())
     suite.addTest(test_lobject.test_suite())
+    suite.addTest(test_async.test_suite())
     return suite
 
 if __name__ == '__main__':
diff --git a/tests/test_async.py b/tests/test_async.py
new file mode 100644
index 0000000..006dab0
--- /dev/null
+++ b/tests/test_async.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+import unittest
+
+import psycopg2
+
+import select
+import sys
+if sys.version_info < (3,):
+    import tests
+else:
+    import py3tests as tests
+
+
+class AsyncTests(unittest.TestCase):
+
+    def setUp(self):
+        self.conn = psycopg2.connect(tests.dsn)
+        curs = self.conn.cursor()
+        curs.execute('''
+            CREATE TEMPORARY TABLE table1 (
+              id int PRIMARY KEY
+            )''')
+        self.conn.commit()
+        curs.close()
+
+    def tearDown(self):
+        self.conn.close()
+
+    def test_async_select(self):
+        cur = self.conn.cursor()
+        cur.execute("select 'test', pg_sleep(1)", async=True)
+
+        finished = False
+        while not finished:
+            _, _, _ = select.select([cur.fileno()], [], [])
+            finished = cur.isready()
+
+        self.assertEquals(cur.fetchall()[0][0], 'test')
+
+    def test_async_callproc(self):
+        cur = self.conn.cursor()
+        cur.callproc("pg_sleep", (1, ), True)
+
+        finished = False
+        while not finished:
+            _, _, _ = select.select([cur.fileno()], [], [])
+            finished = cur.isready()
+
+        self.assertEquals(cur.fetchall()[0][0], '')
+
+
+def test_suite():
+    return unittest.TestLoader().loadTestsFromName(__name__)
-- 
1.7.0