~psycopg/psycopg/2.0.x

« back to all changes in this revision

Viewing changes to doc/async.txt

  • Committer: Federico Di Gregorio
  • Date: 2004-11-20 03:18:42 UTC
  • Revision ID: fog-71267f39d9e561596431cc0b01ac295464afb6ca
Added explanation of how asynchronous queries work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
psycopg asynchronous API
 
2
************************
 
3
 
 
4
Program code can initiate an asynchronous query by passing an 'async=1' flag
 
5
to the .execute() method. A very simple example, from the connection to the
 
6
query:
 
7
 
 
8
    conn = psycopg.connect(database='test')
 
9
    curs = conn.cursor()
 
10
    curs.execute("SEECT * from test WHERE fielda > %s", (1971,), async=1)
 
11
    
 
12
From then on any query on other cursors derived from the same connection is
 
13
doomed to fail (and raise an exception) until the original cursor (the one
 
14
executing the query) complete the asynchronous operation. This can happen in
 
15
a number of different ways:
 
16
 
 
17
    1) one of the .fetchXXX() methods is called, effectively blocking untill
 
18
       data has been sent from the backend to the client, terminating the
 
19
       query.
 
20
       
 
21
    2) .cancel() is called. This method tries to abort the current query and
 
22
       will block until the query is aborted or fully executed. The return
 
23
       value is True if the query was successfully aborted or False if it
 
24
       was executed. Query result are discarded in both cases.
 
25
       
 
26
    3) .execute() is called again on the same cursor (.execute() on a
 
27
       different cursor will simply raise an exception.) This waits for the
 
28
       complete execution of the current query, discard any data and execute
 
29
       the new one.
 
30
 
 
31
Note that calling .execute() two times in a row will not abort the former
 
32
query and will temporarily go to synchronous mode until the first of the two
 
33
queries is executed.
 
34
 
 
35
Cursors now have some extra methods that make them usefull during
 
36
asynchronous queries:
 
37
 
 
38
    .fileno()
 
39
      Returns the file descriptor associated with the current connection and
 
40
      make possible to use a cursor in a context where a file object would be
 
41
      expected (like in a select() call.)
 
42
 
 
43
    .isbusy()
 
44
      Returns True if the backend is still processing the query or false if
 
45
      data is ready to be fetched (by one of the .fetchXXX() methods.)
 
46
      
 
47
A code snippet that shows how to use the cursor object in a select() call:
 
48
 
 
49
    import psycopg
 
50
    import select
 
51
        
 
52
    conn = psycopg.connect(database='test')
 
53
    curs = conn.cursor()
 
54
    curs.execute("SEECT * from test WHERE fielda > %s", (1971,), async=1)
 
55
 
 
56
    # wait for input with a maximum timeout of 5 seconds
 
57
    query_ended = False
 
58
    while not query_ended:
 
59
        rread, rwrite, rspec = select([cursor, another_file], [], [], 5)
 
60
        if not cursor.isbusy():
 
61
           query_ended = True
 
62
        # manage input from other sources like other_file, etc.
 
63
    print "Query Results:"
 
64
    for row in cursor:
 
65
        print row