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)
- Linux
- macOS - please note the special instructions for macOS in the link.
@@ -1976,7 +1976,7 @@ cur.execute(
end if;
end;""")
-# Create type
+# Create a type
print("Creating books type UDT_BOOK...")
cur.execute("""
create type %s as object (
@@ -1988,38 +1988,47 @@ cur.execute("""
# Create queue table and queue and start the queue
print("Creating 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.start_queue", (QUEUE_NAME,))
-# Enqueue a few messages
booksType = con.gettype(BOOK_TYPE_NAME)
-book1 = booksType.newobject()
-book1.TITLE = "The Fellowship of the Ring"
-book1.AUTHORS = "Tolkien, J.R.R."
-book1.PRICE = decimal.Decimal("10.99")
-book2 = booksType.newobject()
-book2.TITLE = "Harry Potter and the Philosopher's Stone"
-book2.AUTHORS = "Rowling, J.K."
-book2.PRICE = decimal.Decimal("7.99")
-options = con.enqoptions()
-messageProperties = con.msgproperties()
-for book in (book1, book2):
- print("Enqueuing book", book.TITLE)
- con.enq(QUEUE_NAME, options, messageProperties, book)
-con.commit()
+queue = con.queue(QUEUE_NAME, booksType)
+
+# 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"))
+]
+
+for title, authors, price in BOOK_DATA:
+ book = booksType.newobject()
+ book.TITLE = title
+ book.AUTHORS = authors
+ book.PRICE = price
+ print(title)
+ queue.enqOne(con.msgproperties(payload=book))
+ con.commit()
# Dequeue the messages
-options = con.deqoptions()
-options.navigation = cx_Oracle.DEQ_FIRST_MSG
-options.wait = cx_Oracle.DEQ_NO_WAIT
-while con.deq(QUEUE_NAME, options, messageProperties, book):
- print("Dequeued book", book.TITLE)
-con.commit()
+print("\nDequeuing messages...")
+queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
+while True:
+ props = queue.deqOne()
+ if not props:
+ break
+ print(props.payload.TITLE)
+ con.commit()
+
+print("\nDone.")
This file sets up Advanced Queuing using Oracle's DBMS_AQADM
-package. The queue is used for passing Oracle UDT_BOOK objects.
+package. The queue is used for passing Oracle UDT_BOOK objects. The
+file uses AQ interface features enhanced in cx_Oracle 7.2.
Run the file:
@@ -2030,14 +2039,37 @@ package. The queue is used for passing Oracle UDT_BOOK objects.
To experiment, split the code into three files: one to create and
start the queue, and two other files to queue and dequeue messages.
Experiment running the queue and dequeue files concurrently in
-separate terminal windows. If you are stuck, look in the
-solutions directory at the aq-dequeue.py,
-aq-enqueue.py and aq-queuestart.py
-files.
+separate terminal windows.
+
+Try removing the commit() call in
+aq-dequeue.py. Now run aq-enqueue.py once
+and then aq-dequeue.py several times. The same messages
+will be available each time you try to dequeue them.
+
+Change aq-dequeue.py to commit in a separate
+transaction by changing the "visibility" setting:
+
+
+queue.deqOptions.visibility = cx_Oracle.DEQ_IMMEDIATE
+
+
+This gives the same behavior as the original code.
+
+Now change the options of enqueued messages so that they expire from the
+queue if they have not been dequeued after four seconds:
+
+
+queue.enqOne(con.msgproperties(payload=book, expiration=4))
+
+
+Now run aq-enqueue.py and wait four seconds before you
+run aq-dequeue.py. There should be no messages to
+dequeue.
+
+If you are stuck, look in the solutions directory at
+the aq-dequeue.py, aq-enqueue.py and
+aq-queuestart.py files.
-Try changing the dequeue options and mode. For example change the
-dequeue options.wait value to
-cx_Oracle.DEQ_WAIT_FOREVER.
diff --git a/samples/tutorial/aq.py b/samples/tutorial/aq.py
index 1e795bb..a345135 100644
--- a/samples/tutorial/aq.py
+++ b/samples/tutorial/aq.py
@@ -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
@@ -32,7 +32,7 @@ cur.execute(
end if;
end;""")
-# Create type
+# Create a type
print("Creating books type UDT_BOOK...")
cur.execute("""
create type %s as object (
@@ -44,31 +44,39 @@ cur.execute("""
# Create queue table and queue and start the queue
print("Creating 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.start_queue", (QUEUE_NAME,))
-# Enqueue a few messages
booksType = con.gettype(BOOK_TYPE_NAME)
-book1 = booksType.newobject()
-book1.TITLE = "The Fellowship of the Ring"
-book1.AUTHORS = "Tolkien, J.R.R."
-book1.PRICE = decimal.Decimal("10.99")
-book2 = booksType.newobject()
-book2.TITLE = "Harry Potter and the Philosopher's Stone"
-book2.AUTHORS = "Rowling, J.K."
-book2.PRICE = decimal.Decimal("7.99")
-options = con.enqoptions()
-messageProperties = con.msgproperties()
-for book in (book1, book2):
- print("Enqueuing book", book.TITLE)
- con.enq(QUEUE_NAME, options, messageProperties, book)
-con.commit()
+queue = con.queue(QUEUE_NAME, booksType)
+
+# 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"))
+]
+
+for title, authors, price in BOOK_DATA:
+ book = booksType.newobject()
+ book.TITLE = title
+ book.AUTHORS = authors
+ book.PRICE = price
+ print(title)
+ queue.enqOne(con.msgproperties(payload=book))
+ con.commit()
# Dequeue the messages
-options = con.deqoptions()
-options.navigation = cx_Oracle.DEQ_FIRST_MSG
-options.wait = cx_Oracle.DEQ_NO_WAIT
-while con.deq(QUEUE_NAME, options, messageProperties, book):
- print("Dequeued book", book.TITLE)
-con.commit()
+print("\nDequeuing messages...")
+queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
+while True:
+ props = queue.deqOne()
+ if not props:
+ break
+ print(props.payload.TITLE)
+ con.commit()
+
+print("\nDone.")
diff --git a/samples/tutorial/solutions/aq-dequeue.py b/samples/tutorial/solutions/aq-dequeue.py
index 9178bd4..706f69e 100644
--- a/samples/tutorial/solutions/aq-dequeue.py
+++ b/samples/tutorial/solutions/aq-dequeue.py
@@ -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
@@ -20,12 +20,16 @@ QUEUE_NAME = "BOOKS"
QUEUE_TABLE_NAME = "BOOK_QUEUE_TABLE"
# 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)
-book = booksType.newobject()
-while con.deq(QUEUE_NAME, options, messageProperties, book):
- print("Dequeued book", book.TITLE)
-con.commit()
+queue = con.queue(QUEUE_NAME, booksType)
+queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
+queue.deqOptions.visibility = cx_Oracle.DEQ_IMMEDIATE
+
+print("\nDequeuing messages...")
+while True:
+ props = queue.deqOne()
+ if not props:
+ break
+ print(props.payload.TITLE)
+
+print("\nDone.")
diff --git a/samples/tutorial/solutions/aq-enqueue.py b/samples/tutorial/solutions/aq-enqueue.py
index baf15ad..89055bd 100644
--- a/samples/tutorial/solutions/aq-enqueue.py
+++ b/samples/tutorial/solutions/aq-enqueue.py
@@ -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
@@ -20,18 +20,21 @@ QUEUE_NAME = "BOOKS"
QUEUE_TABLE_NAME = "BOOK_QUEUE_TABLE"
# 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)
-book1 = booksType.newobject()
-book1.TITLE = "The Fellowship of the Ring"
-book1.AUTHORS = "Tolkien, J.R.R."
-book1.PRICE = decimal.Decimal("10.99")
-book2 = booksType.newobject()
-book2.TITLE = "Harry Potter and the Philosopher's Stone"
-book2.AUTHORS = "Rowling, J.K."
-book2.PRICE = decimal.Decimal("7.99")
-options = con.enqoptions()
-messageProperties = con.msgproperties()
-for book in (book1, book2):
- print("Enqueuing book", book.TITLE)
- con.enq(QUEUE_NAME, options, messageProperties, book)
-con.commit()
+queue = con.queue(QUEUE_NAME, booksType)
+
+for title, authors, price in BOOK_DATA:
+ book = booksType.newobject()
+ book.TITLE = title
+ book.AUTHORS = authors
+ book.PRICE = price
+ print(title)
+ queue.enqOne(con.msgproperties(payload=book, expiration=4))
+ con.commit()
diff --git a/samples/tutorial/solutions/aq-queuestart.py b/samples/tutorial/solutions/aq-queuestart.py
index ceee45a..929c1f3 100644
--- a/samples/tutorial/solutions/aq-queuestart.py
+++ b/samples/tutorial/solutions/aq-queuestart.py
@@ -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
@@ -32,7 +32,7 @@ cur.execute(
end if;
end;""")
-# Create type
+# Create a type
print("Creating books type UDT_BOOK...")
cur.execute("""
create type %s as object (
@@ -44,6 +44,6 @@ cur.execute("""
# Create queue table and queue and start the queue
print("Creating 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.start_queue", (QUEUE_NAME,))