Skip to content

Commit cf61122

Browse files
authored
Update Python examples for cx_Oracle 7.2 (oracle-samples#57)
1 parent bcacc71 commit cf61122

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2698
-137
lines changed

python/AdvancedQueuingNotification.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#------------------------------------------------------------------------------
2+
# Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3+
#------------------------------------------------------------------------------
4+
5+
#------------------------------------------------------------------------------
6+
# AdvancedQueuingNotification.py
7+
# This script demonstrates using advanced queuing notification. Once this
8+
# script is running, use another session to enqueue a few messages to the
9+
# "BOOKS" queue. This is most easily accomplished by running the
10+
# AdvancedQueuing sample.
11+
#
12+
# This script requires cx_Oracle 6.4 and higher.
13+
#------------------------------------------------------------------------------
14+
15+
from __future__ import print_function
16+
17+
import cx_Oracle
18+
import SampleEnv
19+
import threading
20+
import time
21+
22+
registered = True
23+
24+
def callback(message):
25+
global registered
26+
print("Message type:", message.type)
27+
if message.type == cx_Oracle.EVENT_DEREG:
28+
print("Deregistration has taken place...")
29+
registered = False
30+
return
31+
print("Queue name:", message.queueName)
32+
print("Consumer name:", message.consumerName)
33+
34+
connection = cx_Oracle.connect(SampleEnv.GetMainConnectString(), events = True)
35+
sub = connection.subscribe(namespace = cx_Oracle.SUBSCR_NAMESPACE_AQ,
36+
name = "BOOKS", callback = callback, timeout = 300)
37+
print("Subscription:", sub)
38+
print("--> Connection:", sub.connection)
39+
print("--> Callback:", sub.callback)
40+
print("--> Namespace:", sub.namespace)
41+
print("--> Protocol:", sub.protocol)
42+
print("--> Timeout:", sub.timeout)
43+
44+
while registered:
45+
print("Waiting for notifications....")
46+
time.sleep(5)
47+

python/AppContext.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#------------------------------------------------------------------------------
2-
# Copyright 2016, 2017, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
33
#
44
# Portions Copyright 2007-2015, Anthony Tuininga. All rights reserved.
55
#
@@ -19,17 +19,18 @@
1919
from __future__ import print_function
2020

2121
import cx_Oracle
22+
import SampleEnv
2223

2324
# define constants used throughout the script; adjust as desired
24-
CONNECT_STRING = "cx_Oracle/dev@localhost/orcl"
2525
APP_CTX_NAMESPACE = "CLIENTCONTEXT"
2626
APP_CTX_ENTRIES = [
2727
( APP_CTX_NAMESPACE, "ATTR1", "VALUE1" ),
2828
( APP_CTX_NAMESPACE, "ATTR2", "VALUE2" ),
2929
( APP_CTX_NAMESPACE, "ATTR3", "VALUE3" )
3030
]
3131

32-
connection = cx_Oracle.Connection(CONNECT_STRING, appcontext = APP_CTX_ENTRIES)
32+
connection = cx_Oracle.connect(SampleEnv.GetMainConnectString(),
33+
appcontext = APP_CTX_ENTRIES)
3334
cursor = connection.cursor()
3435
for namespace, name, value in APP_CTX_ENTRIES:
3536
cursor.execute("select sys_context(:1, :2) from dual", (namespace, name))

python/ArrayDMLRowCounts.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#------------------------------------------------------------------------------
2+
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3+
#------------------------------------------------------------------------------
4+
5+
#------------------------------------------------------------------------------
6+
# ArrayDMLRowCounts.py
7+
#
8+
# Demonstrate the use of the 12.1 feature that allows cursor.executemany()
9+
# to return the number of rows affected by each individual execution as a list.
10+
# The parameter "arraydmlrowcounts" must be set to True in the call to
11+
# cursor.executemany() after which cursor.getarraydmlrowcounts() can be called.
12+
#
13+
# This script requires cx_Oracle 5.2 and higher.
14+
#------------------------------------------------------------------------------
15+
16+
from __future__ import print_function
17+
18+
import cx_Oracle
19+
import SampleEnv
20+
21+
connection = cx_Oracle.connect(SampleEnv.GetMainConnectString())
22+
cursor = connection.cursor()
23+
24+
# show the number of rows for each parent ID as a means of verifying the
25+
# output from the delete statement
26+
for parentId, count in cursor.execute("""
27+
select ParentId, count(*)
28+
from ChildTable
29+
group by ParentId
30+
order by ParentId"""):
31+
print("Parent ID:", parentId, "has", int(count), "rows.")
32+
print()
33+
34+
# delete the following parent IDs only
35+
parentIdsToDelete = [20, 30, 50]
36+
37+
print("Deleting Parent IDs:", parentIdsToDelete)
38+
print()
39+
40+
# enable array DML row counts for each iteration executed in executemany()
41+
cursor.executemany("""
42+
delete from ChildTable
43+
where ParentId = :1""",
44+
[(i,) for i in parentIdsToDelete],
45+
arraydmlrowcounts = True)
46+
47+
# display the number of rows deleted for each parent ID
48+
rowCounts = cursor.getarraydmlrowcounts()
49+
for parentId, count in zip(parentIdsToDelete, rowCounts):
50+
print("Parent ID:", parentId, "deleted", count, "rows.")
51+

python/BatchErrors.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#------------------------------------------------------------------------------
2+
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3+
#------------------------------------------------------------------------------
4+
5+
#------------------------------------------------------------------------------
6+
# BatchErrors.py
7+
#
8+
# Demonstrate the use of the Oracle Database 12.1 feature that allows
9+
# cursor.executemany() to complete successfully, even if errors take
10+
# place during the execution of one or more of the individual
11+
# executions. The parameter "batcherrors" must be set to True in the
12+
# call to cursor.executemany() after which cursor.getbatcherrors() can
13+
# be called, which will return a list of error objects.
14+
#
15+
# This script requires cx_Oracle 5.2 and higher.
16+
#------------------------------------------------------------------------------
17+
18+
from __future__ import print_function
19+
20+
import cx_Oracle
21+
import SampleEnv
22+
23+
connection = cx_Oracle.connect(SampleEnv.GetMainConnectString())
24+
cursor = connection.cursor()
25+
26+
# define data to insert
27+
dataToInsert = [
28+
(1016, 10, 'Child B of Parent 10'),
29+
(1017, 10, 'Child C of Parent 10'),
30+
(1018, 20, 'Child D of Parent 20'),
31+
(1018, 20, 'Child D of Parent 20'), # duplicate key
32+
(1019, 30, 'Child C of Parent 30'),
33+
(1020, 30, 'Child D of Parent 40'),
34+
(1021, 60, 'Child A of Parent 60'), # parent does not exist
35+
(1022, 40, 'Child F of Parent 40'),
36+
]
37+
38+
# retrieve the number of rows in the table
39+
cursor.execute("""
40+
select count(*)
41+
from ChildTable""")
42+
count, = cursor.fetchone()
43+
print("number of rows in child table:", int(count))
44+
print("number of rows to insert:", len(dataToInsert))
45+
46+
# old method: executemany() with data errors results in stoppage after the
47+
# first error takes place; the row count is updated to show how many rows
48+
# actually succeeded
49+
try:
50+
cursor.executemany("insert into ChildTable values (:1, :2, :3)",
51+
dataToInsert)
52+
except cx_Oracle.DatabaseError as e:
53+
error, = e.args
54+
print("FAILED with error:", error.message)
55+
print("number of rows which succeeded:", cursor.rowcount)
56+
57+
# demonstrate that the row count is accurate
58+
cursor.execute("""
59+
select count(*)
60+
from ChildTable""")
61+
count, = cursor.fetchone()
62+
print("number of rows in child table after failed insert:", int(count))
63+
64+
# roll back so we can perform the same work using the new method
65+
connection.rollback()
66+
67+
# new method: executemany() with batch errors enabled (and array DML row counts
68+
# also enabled) results in no immediate error being raised
69+
cursor.executemany("insert into ChildTable values (:1, :2, :3)", dataToInsert,
70+
batcherrors = True, arraydmlrowcounts = True)
71+
72+
# where errors have taken place, the row count is 0; otherwise it is 1
73+
rowCounts = cursor.getarraydmlrowcounts()
74+
print("Array DML row counts:", rowCounts)
75+
76+
# display the errors that have taken place
77+
errors = cursor.getbatcherrors()
78+
print("number of errors which took place:", len(errors))
79+
for error in errors:
80+
print("Error", error.message.rstrip(), "at row offset", error.offset)
81+
82+
# demonstrate that all of the rows without errors have been successfully
83+
# inserted
84+
cursor.execute("""
85+
select count(*)
86+
from ChildTable""")
87+
count, = cursor.fetchone()
88+
print("number of rows in child table after successful insert:", int(count))

python/BindInsert.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#------------------------------------------------------------------------------
2+
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3+
#------------------------------------------------------------------------------
4+
5+
#------------------------------------------------------------------------------
6+
# BindInsert.py
7+
#
8+
# Demonstrate how to insert a row into a table using bind variables.
9+
#------------------------------------------------------------------------------
10+
11+
from __future__ import print_function
12+
13+
import cx_Oracle
14+
import SampleEnv
15+
16+
connection = cx_Oracle.connect(SampleEnv.GetMainConnectString())
17+
18+
rows = [ (1, "First" ),
19+
(2, "Second" ),
20+
(3, "Third" ),
21+
(4, "Fourth" ),
22+
(5, "Fifth" ),
23+
(6, "Sixth" ),
24+
(7, "Seventh" ) ]
25+
26+
cursor = connection.cursor()
27+
cursor.executemany("insert into mytab(id, data) values (:1, :2)", rows)
28+
29+
# Don't commit - this lets us run the demo multiple times
30+
#connection.commit()
31+
32+
# Now query the results back
33+
34+
for row in cursor.execute('select * from mytab'):
35+
print(row)
36+

python/BindQuery.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#------------------------------------------------------------------------------
2+
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3+
#------------------------------------------------------------------------------
4+
5+
#------------------------------------------------------------------------------
6+
# BindQuery.py
7+
#
8+
# Demonstrate how to perform a simple query limiting the rows retrieved using
9+
# a bind variable. Since the query that is executed is identical, no additional
10+
# parsing is required, thereby reducing overhead and increasing performance. It
11+
# also permits data to be bound without having to be concerned about escaping
12+
# special characters or SQL injection attacks.
13+
#------------------------------------------------------------------------------
14+
15+
from __future__ import print_function
16+
17+
import cx_Oracle
18+
import SampleEnv
19+
20+
connection = cx_Oracle.connect(SampleEnv.GetMainConnectString())
21+
22+
cursor = connection.cursor()
23+
sql = 'select * from SampleQueryTab where id = :bvid'
24+
25+
print("Query results with id = 4")
26+
for row in cursor.execute(sql, bvid = 4):
27+
print(row)
28+
print()
29+
30+
print("Query results with id = 1")
31+
for row in cursor.execute(sql, bvid = 1):
32+
print(row)
33+
print()
34+

python/BulkAQ.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#------------------------------------------------------------------------------
2+
# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3+
#
4+
# Portions Copyright 2007-2015, Anthony Tuininga. All rights reserved.
5+
#
6+
# Portions Copyright 2001-2007, Computronix (Canada) Ltd., Edmonton, Alberta,
7+
# Canada. All rights reserved.
8+
#------------------------------------------------------------------------------
9+
10+
#------------------------------------------------------------------------------
11+
# BulkAQ.py
12+
# This script demonstrates how to use bulk enqueuing and dequeuing of
13+
# messages with advanced queuing using cx_Oracle. It makes use of a RAW queue
14+
# created in the sample setup.
15+
#
16+
# This script requires cx_Oracle 7.2 and higher.
17+
#------------------------------------------------------------------------------
18+
19+
from __future__ import print_function
20+
21+
import cx_Oracle
22+
import SampleEnv
23+
24+
QUEUE_NAME = "DEMO_RAW_QUEUE"
25+
PAYLOAD_DATA = [
26+
"The first message",
27+
"The second message",
28+
"The third message",
29+
"The fourth message",
30+
"The fifth message",
31+
"The sixth message",
32+
"The seventh message",
33+
"The eighth message",
34+
"The ninth message",
35+
"The tenth message",
36+
"The eleventh message",
37+
"The twelfth and final message"
38+
]
39+
40+
# connect to database
41+
connection = cx_Oracle.connect(SampleEnv.GetMainConnectString())
42+
cursor = connection.cursor()
43+
44+
# create queue
45+
queue = connection.queue(QUEUE_NAME)
46+
queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
47+
queue.deqOptions.navigation = cx_Oracle.DEQ_FIRST_MSG
48+
49+
# dequeue all existing messages to ensure the queue is empty, just so that
50+
# the results are consistent
51+
while queue.deqOne():
52+
pass
53+
54+
# enqueue a few messages
55+
print("Enqueuing messages...")
56+
batchSize = 6
57+
dataToEnq = PAYLOAD_DATA
58+
while dataToEnq:
59+
batchData = dataToEnq[:batchSize]
60+
dataToEnq = dataToEnq[batchSize:]
61+
messages = [connection.msgproperties(payload=d) for d in batchData]
62+
for data in batchData:
63+
print(data)
64+
queue.enqMany(messages)
65+
connection.commit()
66+
67+
# dequeue the messages
68+
print("\nDequeuing messages...")
69+
batchSize = 8
70+
while True:
71+
messages = queue.deqMany(batchSize)
72+
if not messages:
73+
break
74+
for props in messages:
75+
print(props.payload.decode())
76+
connection.commit()
77+
print("\nDone.")

0 commit comments

Comments
 (0)