Adjusted tutorial to use new AQ syntax.

This commit is contained in:
Anthony Tuininga 2019-06-19 16:02:55 -06:00
parent e6a825db27
commit 3c4d83fe6c
5 changed files with 130 additions and 83 deletions

View File

@ -104,7 +104,7 @@
<ol> <ol>
<li><a target="_blank" href="https://www.python.org/">Python</a> (3.6 preferred but 2.7 should work)</li> <li><a target="_blank" href="https://www.python.org/">Python</a> (3.6 preferred but 2.7 should work)</li>
<li>cx_Oracle (version 7 preferred but 6.3 or later should work) and Oracle Instant Client Package - Basic (version 18.3 preferred but 12.2 should work) <li>cx_Oracle (version 7.2 preferred but 6.3 or later should work, except for the section on Advanced Queuing which requires version 7.2 or later) and Oracle Instant Client Package - Basic (version 19.3 preferred but 18.3 or 12.2 should also work)
<ul> <ul>
<li><a target="_blank" href="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-linux">Linux</a></li> <li><a target="_blank" href="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-linux">Linux</a></li>
<li><a target="_blank" href="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-macos">macOS</a> - please note the special instructions for macOS in the link.</li> <li><a target="_blank" href="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-macos">macOS</a> - please note the special instructions for macOS in the link.</li>
@ -1976,7 +1976,7 @@ cur.execute(
end if; end if;
end;""") end;""")
# Create type # Create a type
print("Creating books type UDT_BOOK...") print("Creating books type UDT_BOOK...")
cur.execute(""" cur.execute("""
create type %s as object ( create type %s as object (
@ -1988,38 +1988,47 @@ cur.execute("""
# Create queue table and queue and start the queue # Create queue table and queue and start the queue
print("Creating queue table...") print("Creating queue table...")
cur.callproc("dbms_aqadm.create_queue_table", cur.callproc("dbms_aqadm.create_queue_table",
(QUEUE_TABLE_NAME, BOOK_TYPE_NAME)) (QUEUE_TABLE_NAME, BOOK_TYPE_NAME))
cur.callproc("dbms_aqadm.create_queue", (QUEUE_NAME, QUEUE_TABLE_NAME)) cur.callproc("dbms_aqadm.create_queue", (QUEUE_NAME, QUEUE_TABLE_NAME))
cur.callproc("dbms_aqadm.start_queue", (QUEUE_NAME,)) cur.callproc("dbms_aqadm.start_queue", (QUEUE_NAME,))
# Enqueue a few messages
booksType = con.gettype(BOOK_TYPE_NAME) booksType = con.gettype(BOOK_TYPE_NAME)
book1 = booksType.newobject() queue = con.queue(QUEUE_NAME, booksType)
book1.TITLE = "The Fellowship of the Ring"
book1.AUTHORS = "Tolkien, J.R.R." # Enqueue a few messages
book1.PRICE = decimal.Decimal("10.99") print("Enqueuing messages...")
book2 = booksType.newobject()
book2.TITLE = "Harry Potter and the Philosopher's Stone" BOOK_DATA = [
book2.AUTHORS = "Rowling, J.K." ("The Fellowship of the Ring", "Tolkien, J.R.R.", decimal.Decimal("10.99")),
book2.PRICE = decimal.Decimal("7.99") ("Harry Potter and the Philosopher's Stone", "Rowling, J.K.",
options = con.enqoptions() decimal.Decimal("7.99"))
messageProperties = con.msgproperties() ]
for book in (book1, book2):
print("Enqueuing book", book.TITLE) for title, authors, price in BOOK_DATA:
con.enq(QUEUE_NAME, options, messageProperties, book) book = booksType.newobject()
con.commit() book.TITLE = title
book.AUTHORS = authors
book.PRICE = price
print(title)
queue.enqOne(con.msgproperties(payload=book))
con.commit()
# Dequeue the messages # Dequeue the messages
options = con.deqoptions() print("\nDequeuing messages...")
options.navigation = cx_Oracle.DEQ_FIRST_MSG queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
options.wait = cx_Oracle.DEQ_NO_WAIT while True:
while con.deq(QUEUE_NAME, options, messageProperties, book): props = queue.deqOne()
print("Dequeued book", book.TITLE) if not props:
con.commit() break
print(props.payload.TITLE)
con.commit()
print("\nDone.")
</pre> </pre>
<p>This file sets up Advanced Queuing using Oracle's DBMS_AQADM <p>This file sets up Advanced Queuing using Oracle's DBMS_AQADM
package. The queue is used for passing Oracle UDT_BOOK objects.</p> package. The queue is used for passing Oracle UDT_BOOK objects. The
file uses AQ interface features enhanced in cx_Oracle 7.2.</p>
<p>Run the file:</p> <p>Run the file:</p>
@ -2030,14 +2039,37 @@ package. The queue is used for passing Oracle UDT_BOOK objects.</p>
<p>To experiment, split the code into three files: one to create and <p>To experiment, split the code into three files: one to create and
start the queue, and two other files to queue and dequeue messages. start the queue, and two other files to queue and dequeue messages.
Experiment running the queue and dequeue files concurrently in Experiment running the queue and dequeue files concurrently in
separate terminal windows. If you are stuck, look in the separate terminal windows.</p>
<code>solutions</code> directory at the <code>aq-dequeue.py</code>,
<code>aq-enqueue.py</code> and <code>aq-queuestart.py</code> <p>Try removing the <code>commit()</code> call in
files.</p> <code>aq-dequeue.py</code>. Now run <code>aq-enqueue.py</code> once
and then <code>aq-dequeue.py</code> several times. The same messages
will be available each time you try to dequeue them.</p>
<p>Change <code>aq-dequeue.py</code> to commit in a separate
transaction by changing the "visibility" setting:</p>
<pre>
queue.deqOptions.visibility = cx_Oracle.DEQ_IMMEDIATE
</pre>
<p>This gives the same behavior as the original code.</p>
<p>Now change the options of enqueued messages so that they expire from the
queue if they have not been dequeued after four seconds:</p>
<pre>
queue.enqOne(con.msgproperties(payload=book, expiration=4))
</pre>
<p>Now run <code>aq-enqueue.py</code> and wait four seconds before you
run <code>aq-dequeue.py</code>. There should be no messages to
dequeue. </p>
<p>If you are stuck, look in the <code>solutions</code> directory at
the <code>aq-dequeue.py</code>, <code>aq-enqueue.py</code> and
<code>aq-queuestart.py</code> files.</p>
<p>Try changing the dequeue options and mode. For example change the
dequeue <code>options.wait</code> value to
<code>cx_Oracle.DEQ_WAIT_FOREVER</code>.</p>
</ul> </ul>
</li> </li>

View File

@ -3,7 +3,7 @@
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
from __future__ import print_function from __future__ import print_function
@ -32,7 +32,7 @@ cur.execute(
end if; end if;
end;""") end;""")
# Create type # Create a type
print("Creating books type UDT_BOOK...") print("Creating books type UDT_BOOK...")
cur.execute(""" cur.execute("""
create type %s as object ( create type %s as object (
@ -44,31 +44,39 @@ cur.execute("""
# Create queue table and queue and start the queue # Create queue table and queue and start the queue
print("Creating queue table...") print("Creating queue table...")
cur.callproc("dbms_aqadm.create_queue_table", cur.callproc("dbms_aqadm.create_queue_table",
(QUEUE_TABLE_NAME, BOOK_TYPE_NAME)) (QUEUE_TABLE_NAME, BOOK_TYPE_NAME))
cur.callproc("dbms_aqadm.create_queue", (QUEUE_NAME, QUEUE_TABLE_NAME)) cur.callproc("dbms_aqadm.create_queue", (QUEUE_NAME, QUEUE_TABLE_NAME))
cur.callproc("dbms_aqadm.start_queue", (QUEUE_NAME,)) cur.callproc("dbms_aqadm.start_queue", (QUEUE_NAME,))
# Enqueue a few messages
booksType = con.gettype(BOOK_TYPE_NAME) booksType = con.gettype(BOOK_TYPE_NAME)
book1 = booksType.newobject() queue = con.queue(QUEUE_NAME, booksType)
book1.TITLE = "The Fellowship of the Ring"
book1.AUTHORS = "Tolkien, J.R.R." # Enqueue a few messages
book1.PRICE = decimal.Decimal("10.99") print("Enqueuing messages...")
book2 = booksType.newobject()
book2.TITLE = "Harry Potter and the Philosopher's Stone" BOOK_DATA = [
book2.AUTHORS = "Rowling, J.K." ("The Fellowship of the Ring", "Tolkien, J.R.R.", decimal.Decimal("10.99")),
book2.PRICE = decimal.Decimal("7.99") ("Harry Potter and the Philosopher's Stone", "Rowling, J.K.",
options = con.enqoptions() decimal.Decimal("7.99"))
messageProperties = con.msgproperties() ]
for book in (book1, book2):
print("Enqueuing book", book.TITLE) for title, authors, price in BOOK_DATA:
con.enq(QUEUE_NAME, options, messageProperties, book) book = booksType.newobject()
con.commit() book.TITLE = title
book.AUTHORS = authors
book.PRICE = price
print(title)
queue.enqOne(con.msgproperties(payload=book))
con.commit()
# Dequeue the messages # Dequeue the messages
options = con.deqoptions() print("\nDequeuing messages...")
options.navigation = cx_Oracle.DEQ_FIRST_MSG queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
options.wait = cx_Oracle.DEQ_NO_WAIT while True:
while con.deq(QUEUE_NAME, options, messageProperties, book): props = queue.deqOne()
print("Dequeued book", book.TITLE) if not props:
con.commit() break
print(props.payload.TITLE)
con.commit()
print("\nDone.")

View File

@ -3,7 +3,7 @@
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
from __future__ import print_function from __future__ import print_function
@ -20,12 +20,16 @@ QUEUE_NAME = "BOOKS"
QUEUE_TABLE_NAME = "BOOK_QUEUE_TABLE" QUEUE_TABLE_NAME = "BOOK_QUEUE_TABLE"
# Dequeue the messages # Dequeue the messages
options = con.deqoptions()
options.navigation = cx_Oracle.DEQ_FIRST_MSG
options.wait = cx_Oracle.DEQ_NO_WAIT
messageProperties = con.msgproperties()
booksType = con.gettype(BOOK_TYPE_NAME) booksType = con.gettype(BOOK_TYPE_NAME)
book = booksType.newobject() queue = con.queue(QUEUE_NAME, booksType)
while con.deq(QUEUE_NAME, options, messageProperties, book): queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
print("Dequeued book", book.TITLE) queue.deqOptions.visibility = cx_Oracle.DEQ_IMMEDIATE
con.commit()
print("\nDequeuing messages...")
while True:
props = queue.deqOne()
if not props:
break
print(props.payload.TITLE)
print("\nDone.")

View File

@ -3,7 +3,7 @@
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
from __future__ import print_function from __future__ import print_function
@ -20,18 +20,21 @@ QUEUE_NAME = "BOOKS"
QUEUE_TABLE_NAME = "BOOK_QUEUE_TABLE" QUEUE_TABLE_NAME = "BOOK_QUEUE_TABLE"
# Enqueue a few messages # Enqueue a few messages
print("Enqueuing messages...")
BOOK_DATA = [
("The Fellowship of the Ring", "Tolkien, J.R.R.", decimal.Decimal("10.99")),
("Harry Potter and the Philosopher's Stone", "Rowling, J.K.", decimal.Decimal("7.99"))
]
booksType = con.gettype(BOOK_TYPE_NAME) booksType = con.gettype(BOOK_TYPE_NAME)
book1 = booksType.newobject() queue = con.queue(QUEUE_NAME, booksType)
book1.TITLE = "The Fellowship of the Ring"
book1.AUTHORS = "Tolkien, J.R.R." for title, authors, price in BOOK_DATA:
book1.PRICE = decimal.Decimal("10.99") book = booksType.newobject()
book2 = booksType.newobject() book.TITLE = title
book2.TITLE = "Harry Potter and the Philosopher's Stone" book.AUTHORS = authors
book2.AUTHORS = "Rowling, J.K." book.PRICE = price
book2.PRICE = decimal.Decimal("7.99") print(title)
options = con.enqoptions() queue.enqOne(con.msgproperties(payload=book, expiration=4))
messageProperties = con.msgproperties() con.commit()
for book in (book1, book2):
print("Enqueuing book", book.TITLE)
con.enq(QUEUE_NAME, options, messageProperties, book)
con.commit()

View File

@ -3,7 +3,7 @@
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
from __future__ import print_function from __future__ import print_function
@ -32,7 +32,7 @@ cur.execute(
end if; end if;
end;""") end;""")
# Create type # Create a type
print("Creating books type UDT_BOOK...") print("Creating books type UDT_BOOK...")
cur.execute(""" cur.execute("""
create type %s as object ( create type %s as object (
@ -44,6 +44,6 @@ cur.execute("""
# Create queue table and queue and start the queue # Create queue table and queue and start the queue
print("Creating queue table...") print("Creating queue table...")
cur.callproc("dbms_aqadm.create_queue_table", cur.callproc("dbms_aqadm.create_queue_table",
(QUEUE_TABLE_NAME, BOOK_TYPE_NAME)) (QUEUE_TABLE_NAME, BOOK_TYPE_NAME))
cur.callproc("dbms_aqadm.create_queue", (QUEUE_NAME, QUEUE_TABLE_NAME)) cur.callproc("dbms_aqadm.create_queue", (QUEUE_NAME, QUEUE_TABLE_NAME))
cur.callproc("dbms_aqadm.start_queue", (QUEUE_NAME,)) cur.callproc("dbms_aqadm.start_queue", (QUEUE_NAME,))