Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 28 additions & 15 deletions python/python-oracledb/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Python-oracledb Examples
# Python-oracledb Examples

This directory contains samples for python-oracledb, the Python driver for
Oracle Database.

### Basic Examples

1. The schemas and SQL objects that are referenced in the samples can be
created by running the Python script
[create_schema.py](https://github.com/oracle-samples/oracle-db-examples/blob/main/python/create_schema.py). The
script requires SYSDBA privileges and will prompt for these credentials as
well as the names of the schemas and edition that will be created, unless a
number of environment variables are set as documented in the Python script
[sample_env.py](https://github.com/oracle-samples/oracle-db-examples/blob/main/python/sample_env.py). Run
the script using the following command:
created by running the Python script [create_schema.py][1]. The script
requires SYSDBA privileges and will prompt for these credentials as well as
the names of the schemas and edition that will be created, unless a number
of environment variables are set as documented in the Python script
[sample_env.py][2]. Run the script using the following command:

python create_schema.py

Expand All @@ -19,16 +19,24 @@ Oracle Database.
python query.py

3. After running python-oracledb samples, the schemas and SQL objects can be
dropped by running the Python script
[drop_schema.py](https://github.com/oracle-samples/oracle-db-examples/blob/main/python/drop_schema.py). The
script requires SYSDBA privileges and will prompt for these credentials as
well as the names of the schemas and edition that will be dropped, unless a
number of environment variables are set as documented in the Python script
[sample_env.py](https://github.com/oracle-samples/oracle-db-examples/blob/main/python/sample_env.py). Run
the script using the following command:
dropped by running the Python script [drop_schema.py][3]. The script
requires SYSDBA privileges and will prompt for these credentials as well as
the names of the schemas and edition that will be dropped, unless a number
of environment variables are set as documented in the Python script
[sample_env.py][2]. Run the script using the following command:

python drop_schema.py

### Examples in a Container

The [sample_container](./sample_container) directory has a Dockerfile that will
build a container with the samples and a running Oracle Database.

### Notebooks

The [sample_notebooks](./sample_notebooks) directory has Jupyter notebooks with
runnable examples.

## About python-oracledb

- Python-oracledb is the new name for Oracle's popular Python cx_Oracle driver
Expand Down Expand Up @@ -71,3 +79,8 @@ PyPI: [pypi.org/project/oracledb/](https://pypi.org/project/oracledb/)
Source: [github.com/oracle/python-oracledb](https://github.com/oracle/python-oracledb)

Upgrading: [Upgrading from cx_Oracle 8.3 to python-oracledb](https://python-oracledb.readthedocs.io/en/latest/user_guide/appendix_c.html#upgrading-from-cx-oracle-8-3-to-python-oracledb)


[1]: https://github.com/oracle/python-oracledb/blob/main/samples/create_schema.py
[2]: https://github.com/oracle/python-oracledb/blob/main/samples/sample_env.py
[3]: https://github.com/oracle/python-oracledb/blob/main/samples/drop_schema.py
34 changes: 18 additions & 16 deletions python/python-oracledb/app_context.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#------------------------------------------------------------------------------
# Copyright (c) 2016, 2022, Oracle and/or its affiliates.
# -----------------------------------------------------------------------------
# Copyright (c) 2016, 2023, Oracle and/or its affiliates.
#
# Portions Copyright 2007-2015, Anthony Tuininga. All rights reserved.
#
Expand All @@ -25,15 +25,15 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------

#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# app_context.py
#
# Demonstrates the use of application context. Application context is available
# within logon triggers and can be retrieved by using the function
# sys_context().
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------

import oracledb
import sample_env
Expand All @@ -44,20 +44,22 @@
# client context attributes to be set
APP_CTX_NAMESPACE = "CLIENTCONTEXT"
APP_CTX_ENTRIES = [
( APP_CTX_NAMESPACE, "ATTR1", "VALUE1" ),
( APP_CTX_NAMESPACE, "ATTR2", "VALUE2" ),
( APP_CTX_NAMESPACE, "ATTR3", "VALUE3" )
(APP_CTX_NAMESPACE, "ATTR1", "VALUE1"),
(APP_CTX_NAMESPACE, "ATTR2", "VALUE2"),
(APP_CTX_NAMESPACE, "ATTR3", "VALUE3"),
]

connection = oracledb.connect(user=sample_env.get_main_user(),
password=sample_env.get_main_password(),
dsn=sample_env.get_connect_string(),
appcontext=APP_CTX_ENTRIES)
connection = oracledb.connect(
user=sample_env.get_main_user(),
password=sample_env.get_main_password(),
dsn=sample_env.get_connect_string(),
appcontext=APP_CTX_ENTRIES,
)

with connection.cursor() as cursor:

for namespace, name, value in APP_CTX_ENTRIES:
cursor.execute("select sys_context(:1, :2) from dual",
(namespace, name))
value, = cursor.fetchone()
cursor.execute(
"select sys_context(:1, :2) from dual", (namespace, name)
)
(value,) = cursor.fetchone()
print("Value of context key", name, "is", value)
31 changes: 19 additions & 12 deletions python/python-oracledb/aq_notification.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#------------------------------------------------------------------------------
# Copyright (c) 2018, 2022, Oracle and/or its affiliates.
# -----------------------------------------------------------------------------
# Copyright (c) 2018, 2023, Oracle and/or its affiliates.
#
# This software is dual-licensed to you under the Universal Permissive License
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
Expand All @@ -20,15 +20,15 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------

#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# aq_notification.py
#
# Demonstrates using advanced queuing notification. Once this script is
# running, run object_aq.py in another terminal to enqueue a few messages to
# the "DEMO_BOOK_QUEUE" queue.
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------

import time

Expand All @@ -40,6 +40,7 @@

registered = True


def process_messages(message):
global registered
print("Message type:", message.type)
Expand All @@ -51,14 +52,20 @@ def process_messages(message):
print("Consumer name:", message.consumer_name)
print("Message id:", message.msgid)

connection = oracledb.connect(user=sample_env.get_main_user(),
password=sample_env.get_main_password(),
dsn=sample_env.get_connect_string(),
events=True)

sub = connection.subscribe(namespace=oracledb.SUBSCR_NAMESPACE_AQ,
name="DEMO_BOOK_QUEUE", callback=process_messages,
timeout=300)
connection = oracledb.connect(
user=sample_env.get_main_user(),
password=sample_env.get_main_password(),
dsn=sample_env.get_connect_string(),
events=True,
)

sub = connection.subscribe(
namespace=oracledb.SUBSCR_NAMESPACE_AQ,
name="DEMO_BOOK_QUEUE",
callback=process_messages,
timeout=300,
)
print("Subscription:", sub)
print("--> Connection:", sub.connection)
print("--> Callback:", sub.callback)
Expand Down
42 changes: 23 additions & 19 deletions python/python-oracledb/array_dml_rowcounts.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#------------------------------------------------------------------------------
# Copyright (c) 2016, 2022, Oracle and/or its affiliates.
# -----------------------------------------------------------------------------
# Copyright (c) 2016, 2023, Oracle and/or its affiliates.
#
# This software is dual-licensed to you under the Universal Permissive License
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
Expand All @@ -20,16 +20,16 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------

#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# array_dml_rowcounts.py
#
# Demonstrates the use of the 12.1 feature that allows cursor.executemany()
# to return the number of rows affected by each individual execution as a list.
# The parameter "arraydmlrowcounts" must be set to True in the call to
# cursor.executemany() after which cursor.getarraydmlrowcounts() can be called.
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------

import oracledb
import sample_env
Expand All @@ -38,19 +38,23 @@
if not sample_env.get_is_thin():
oracledb.init_oracle_client(lib_dir=sample_env.get_oracle_client())

connection = oracledb.connect(user=sample_env.get_main_user(),
password=sample_env.get_main_password(),
dsn=sample_env.get_connect_string())
connection = oracledb.connect(
user=sample_env.get_main_user(),
password=sample_env.get_main_password(),
dsn=sample_env.get_connect_string(),
)

with connection.cursor() as cursor:

# show the number of rows for each parent ID as a means of verifying the
# output from the delete statement
for parent_id, count in cursor.execute("""
select ParentId, count(*)
from ChildTable
group by ParentId
order by ParentId"""):
for parent_id, count in cursor.execute(
"""
select ParentId, count(*)
from ChildTable
group by ParentId
order by ParentId
"""
):
print("Parent ID:", parent_id, "has", int(count), "rows.")
print()

Expand All @@ -61,11 +65,11 @@
print()

# enable array DML row counts for each iteration executed in executemany()
cursor.executemany("""
delete from ChildTable
where ParentId = :1""",
[(i,) for i in parent_ids_to_delete],
arraydmlrowcounts = True)
cursor.executemany(
"delete from ChildTable where ParentId = :1",
[(i,) for i in parent_ids_to_delete],
arraydmlrowcounts=True,
)

# display the number of rows deleted for each parent ID
row_counts = cursor.getarraydmlrowcounts()
Expand Down
84 changes: 84 additions & 0 deletions python/python-oracledb/array_dml_rowcounts_async.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# -----------------------------------------------------------------------------
# Copyright (c) 2023, Oracle and/or its affiliates.
#
# This software is dual-licensed to you under the Universal Permissive License
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
# either license.
#
# If you elect to accept the software under the Apache License, Version 2.0,
# the following applies:
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# array_dml_rowcounts_async.py
#
# An asynchronous version of array_dml_rowcounts.py
#
# Demonstrates the use of the 12.1 feature that allows cursor.executemany()
# to return the number of rows affected by each individual execution as a list.
# The parameter "arraydmlrowcounts" must be set to True in the call to
# cursor.executemany() after which cursor.getarraydmlrowcounts() can be called.
# -----------------------------------------------------------------------------

import asyncio

import oracledb
import sample_env


async def main():
connection = await oracledb.connect_async(
user=sample_env.get_main_user(),
password=sample_env.get_main_password(),
dsn=sample_env.get_connect_string(),
)

with connection.cursor() as cursor:
# show the number of rows for each parent ID as a means of verifying
# the output from the delete statement
await cursor.execute(
"""
select ParentId, count(*)
from ChildTable
group by ParentId
order by ParentId
"""
)
async for parent_id, count in cursor:
print("Parent ID:", parent_id, "has", int(count), "rows.")
print()

# delete the following parent IDs only
parent_ids_to_delete = [20, 30, 50]

print("Deleting Parent IDs:", parent_ids_to_delete)
print()

# enable array DML row counts for each iteration executed in
# executemany()
await cursor.executemany(
"delete from ChildTable where ParentId = :1",
[(i,) for i in parent_ids_to_delete],
arraydmlrowcounts=True,
)

# display the number of rows deleted for each parent ID
row_counts = cursor.getarraydmlrowcounts()
for parent_id, count in zip(parent_ids_to_delete, row_counts):
print("Parent ID:", parent_id, "deleted", count, "rows.")


asyncio.run(main())
Loading