@@ -104,7 +104,7 @@ <h2><a name="preface">Preface</a></h2>
104
104
105
105
< ol >
106
106
< li > < a target ="_blank " href ="https://www.python.org/ "> Python</ a > (3.6 preferred but 2.7 should work)</ li >
107
- < 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)
107
+ < 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)
108
108
< ul >
109
109
< li > < a target ="_blank " href ="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-linux "> Linux</ a > </ li >
110
110
< 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 @@ <h4>7.2 Fetching a CLOB as a string</h4>
1976
1976
end if;
1977
1977
end;""")
1978
1978
1979
- # Create type
1979
+ # Create a type
1980
1980
print("Creating books type UDT_BOOK...")
1981
1981
cur.execute("""
1982
1982
create type %s as object (
@@ -1988,38 +1988,47 @@ <h4>7.2 Fetching a CLOB as a string</h4>
1988
1988
# Create queue table and queue and start the queue
1989
1989
print("Creating queue table...")
1990
1990
cur.callproc("dbms_aqadm.create_queue_table",
1991
- (QUEUE_TABLE_NAME, BOOK_TYPE_NAME))
1991
+ (QUEUE_TABLE_NAME, BOOK_TYPE_NAME))
1992
1992
cur.callproc("dbms_aqadm.create_queue", (QUEUE_NAME, QUEUE_TABLE_NAME))
1993
1993
cur.callproc("dbms_aqadm.start_queue", (QUEUE_NAME,))
1994
1994
1995
- # Enqueue a few messages
1996
1995
booksType = con.gettype(BOOK_TYPE_NAME)
1997
- book1 = booksType.newobject()
1998
- book1.TITLE = "The Fellowship of the Ring"
1999
- book1.AUTHORS = "Tolkien, J.R.R."
2000
- book1.PRICE = decimal.Decimal("10.99")
2001
- book2 = booksType.newobject()
2002
- book2.TITLE = "Harry Potter and the Philosopher's Stone"
2003
- book2.AUTHORS = "Rowling, J.K."
2004
- book2.PRICE = decimal.Decimal("7.99")
2005
- options = con.enqoptions()
2006
- messageProperties = con.msgproperties()
2007
- for book in (book1, book2):
2008
- print("Enqueuing book", book.TITLE)
2009
- con.enq(QUEUE_NAME, options, messageProperties, book)
2010
- con.commit()
1996
+ queue = con.queue(QUEUE_NAME, booksType)
1997
+
1998
+ # Enqueue a few messages
1999
+ print("Enqueuing messages...")
2000
+
2001
+ BOOK_DATA = [
2002
+ ("The Fellowship of the Ring", "Tolkien, J.R.R.", decimal.Decimal("10.99")),
2003
+ ("Harry Potter and the Philosopher's Stone", "Rowling, J.K.",
2004
+ decimal.Decimal("7.99"))
2005
+ ]
2006
+
2007
+ for title, authors, price in BOOK_DATA:
2008
+ book = booksType.newobject()
2009
+ book.TITLE = title
2010
+ book.AUTHORS = authors
2011
+ book.PRICE = price
2012
+ print(title)
2013
+ queue.enqOne(con.msgproperties(payload=book))
2014
+ con.commit()
2011
2015
2012
2016
# Dequeue the messages
2013
- options = con.deqoptions()
2014
- options.navigation = cx_Oracle.DEQ_FIRST_MSG
2015
- options.wait = cx_Oracle.DEQ_NO_WAIT
2016
- while con.deq(QUEUE_NAME, options, messageProperties, book):
2017
- print("Dequeued book", book.TITLE)
2018
- con.commit()
2017
+ print("\nDequeuing messages...")
2018
+ queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
2019
+ while True:
2020
+ props = queue.deqOne()
2021
+ if not props:
2022
+ break
2023
+ print(props.payload.TITLE)
2024
+ con.commit()
2025
+
2026
+ print("\nDone.")
2019
2027
</ pre >
2020
2028
2021
2029
< p > This file sets up Advanced Queuing using Oracle's DBMS_AQADM
2022
- package. The queue is used for passing Oracle UDT_BOOK objects.</ p >
2030
+ package. The queue is used for passing Oracle UDT_BOOK objects. The
2031
+ file uses AQ interface features enhanced in cx_Oracle 7.2.</ p >
2023
2032
2024
2033
< p > Run the file:</ p >
2025
2034
@@ -2030,14 +2039,37 @@ <h4>7.2 Fetching a CLOB as a string</h4>
2030
2039
< p > To experiment, split the code into three files: one to create and
2031
2040
start the queue, and two other files to queue and dequeue messages.
2032
2041
Experiment running the queue and dequeue files concurrently in
2033
- separate terminal windows. If you are stuck, look in the
2034
- < code > solutions</ code > directory at the < code > aq-dequeue.py</ code > ,
2035
- < code > aq-enqueue.py</ code > and < code > aq-queuestart.py</ code >
2036
- files.</ p >
2037
-
2038
- < p > Try changing the dequeue options and mode. For example change the
2039
- dequeue < code > options.wait</ code > value to
2040
- < code > cx_Oracle.DEQ_WAIT_FOREVER</ code > .</ p >
2042
+ separate terminal windows.</ p >
2043
+
2044
+ < p > Try removing the < code > commit()</ code > call in
2045
+ < code > aq-dequeue.py</ code > . Now run < code > aq-enqueue.py</ code > once
2046
+ and then < code > aq-dequeue.py</ code > several times. The same messages
2047
+ will be available each time you try to dequeue them.</ p >
2048
+
2049
+ < p > Change < code > aq-dequeue.py</ code > to commit in a separate
2050
+ transaction by changing the "visibility" setting:</ p >
2051
+
2052
+ < pre >
2053
+ queue.deqOptions.visibility = cx_Oracle.DEQ_IMMEDIATE
2054
+ </ pre >
2055
+
2056
+ < p > This gives the same behavior as the original code.</ p >
2057
+
2058
+ < p > Now change the options of enqueued messages so that they expire from the
2059
+ queue if they have not been dequeued after four seconds:</ p >
2060
+
2061
+ < pre >
2062
+ queue.enqOne(con.msgproperties(payload=book, expiration=4))
2063
+ </ pre >
2064
+
2065
+ < p > Now run < code > aq-enqueue.py</ code > and wait four seconds before you
2066
+ run < code > aq-dequeue.py</ code > . There should be no messages to
2067
+ dequeue. </ p >
2068
+
2069
+ < p > If you are stuck, look in the < code > solutions</ code > directory at
2070
+ the < code > aq-dequeue.py</ code > , < code > aq-enqueue.py</ code > and
2071
+ < code > aq-queuestart.py</ code > files.</ p >
2072
+
2041
2073
2042
2074
</ ul >
2043
2075
</ li >
0 commit comments