Skip to content

Commit 3fb231b

Browse files
Update tutorial.
1 parent 6b86d9b commit 3fb231b

39 files changed

+2610
-902
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ repos:
1414
rev: v0.0.291
1515
hooks:
1616
- id: ruff
17+
exclude: ^samples/

samples/tutorial/Python-and-Oracle-Database-The-New-Wave-of-Scripting.html

Lines changed: 1926 additions & 831 deletions
Large diffs are not rendered by default.

samples/tutorial/aq.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# -----------------------------------------------------------------------------
44

55
# -----------------------------------------------------------------------------
6-
# Copyright (c) 2017, 2023, Oracle and/or its affiliates.
6+
# Copyright (c) 2017, 2025, Oracle and/or its affiliates.
77
#
88
# This software is dual-licensed to you under the Universal Permissive License
99
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -28,7 +28,7 @@
2828

2929
import oracledb
3030
import decimal
31-
import db_config_thick as db_config
31+
import db_config
3232

3333
con = oracledb.connect(
3434
user=db_config.user, password=db_config.pw, dsn=db_config.dsn

samples/tutorial/async_gather.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# -----------------------------------------------------------------------------
2+
# async_gather.py (Section 17.1)
3+
# -----------------------------------------------------------------------------
4+
5+
# -----------------------------------------------------------------------------
6+
# Copyright (c) 2025, Oracle and/or its affiliates.
7+
#
8+
# This software is dual-licensed to you under the Universal Permissive License
9+
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
10+
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
11+
# either license.
12+
#
13+
# If you elect to accept the software under the Apache License, Version 2.0,
14+
# the following applies:
15+
#
16+
# Licensed under the Apache License, Version 2.0 (the "License");
17+
# you may not use this file except in compliance with the License.
18+
# You may obtain a copy of the License at
19+
#
20+
# https://www.apache.org/licenses/LICENSE-2.0
21+
#
22+
# Unless required by applicable law or agreed to in writing, software
23+
# distributed under the License is distributed on an "AS IS" BASIS,
24+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25+
# See the License for the specific language governing permissions and
26+
# limitations under the License.
27+
# -----------------------------------------------------------------------------
28+
29+
import asyncio
30+
import oracledb
31+
import db_config
32+
33+
# Number of coroutines to run
34+
CONCURRENCY = 5
35+
36+
# Maximum connection pool size
37+
POOLSIZE = 5
38+
39+
# Query the unique session identifier/serial number combination of a connection
40+
SQL = """select unique current_timestamp as ct, sid||'-'||serial# as sidser
41+
from v$session_connect_info
42+
where sid = sys_context('userenv', 'sid')"""
43+
44+
45+
# Show the unique session identifier/serial number of each connection that the
46+
# pool opens
47+
async def init_session(connection, requested_tag):
48+
res = await connection.fetchone(SQL)
49+
print(res[0].strftime("%H:%M:%S.%f"), "- init_session SID-SERIAL#", res[1])
50+
51+
52+
# The coroutine simply shows the session identifier/serial number of the
53+
# connection returned by the pool.acquire() call
54+
async def query(pool):
55+
async with pool.acquire() as connection:
56+
await connection.callproc("dbms_session.sleep", [1])
57+
res = await connection.fetchone(SQL)
58+
print(res[0].strftime("%H:%M:%S.%f"), "- query SID-SERIAL#", res[1])
59+
60+
61+
async def main():
62+
63+
pool = oracledb.create_pool_async(
64+
user=db_config.user,
65+
password=db_config.pw,
66+
dsn=db_config.dsn,
67+
min=1,
68+
max=POOLSIZE,
69+
session_callback=init_session,
70+
)
71+
72+
coroutines = [query(pool) for i in range(CONCURRENCY)]
73+
74+
await asyncio.gather(*coroutines)
75+
76+
await pool.close()
77+
78+
79+
asyncio.run(main())

samples/tutorial/bind_sdo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# -----------------------------------------------------------------------------
44

55
# -----------------------------------------------------------------------------
6-
# Copyright (c) 2017, 2023, Oracle and/or its affiliates.
6+
# Copyright (c) 2017, 2025, Oracle and/or its affiliates.
77
#
88
# This software is dual-licensed to you under the Universal Permissive License
99
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -27,7 +27,7 @@
2727
# -----------------------------------------------------------------------------
2828

2929
import oracledb
30-
import db_config_thick as db_config
30+
import db_config
3131

3232
con = oracledb.connect(
3333
user=db_config.user, password=db_config.pw, dsn=db_config.dsn

samples/tutorial/connect_params2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# -----------------------------------------------------------------------------
44

55
# -----------------------------------------------------------------------------
6-
# Copyright (c) 2017, 2023, Oracle and/or its affiliates.
6+
# Copyright (c) 2017, 2025, Oracle and/or its affiliates.
77
#
88
# This software is dual-licensed to you under the Universal Permissive License
99
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -30,7 +30,7 @@
3030
import db_config
3131

3232
params = oracledb.ConnectParams(
33-
host="localhost", port=1521, service_name="orclpdb"
33+
host="localhost", port=1521, service_name="freepdb1"
3434
)
3535
con = oracledb.connect(
3636
user=db_config.user, password=db_config.pw, params=params

samples/tutorial/create_user.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# -----------------------------------------------------------------------------
44

55
# -----------------------------------------------------------------------------
6-
# Copyright (c) 2022, 2023, Oracle and/or its affiliates.
6+
# Copyright (c) 2022, 2025, Oracle and/or its affiliates.
77
#
88
# This software is dual-licensed to you under the Universal Permissive License
99
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -34,8 +34,8 @@
3434

3535
# default values
3636
PYTHON_USER = "pythondemo"
37-
PYTHON_CONNECT_STRING = "localhost/orclpdb"
38-
PYTHON_DRCP_CONNECT_STRING = "localhost/orclpdb:pooled"
37+
PYTHON_CONNECT_STRING = "localhost/freepdb1"
38+
PYTHON_DRCP_CONNECT_STRING = "localhost/freepdb1:pooled"
3939

4040
# dictionary containing all parameters; these are acquired as needed by the
4141
# methods below (which should be used instead of consulting this dictionary

samples/tutorial/db_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -----------------------------------------------------------------------------
2-
# Copyright (c) 2022, 2023, Oracle and/or its affiliates.
2+
# Copyright (c) 2022, 2025, Oracle and/or its affiliates.
33
#
44
# This software is dual-licensed to you under the Universal Permissive License
55
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -32,7 +32,7 @@
3232

3333
user = os.environ.get("PYTHON_USER", "pythondemo")
3434

35-
dsn = os.environ.get("PYTHON_CONNECT_STRING", "localhost/orclpdb")
35+
dsn = os.environ.get("PYTHON_CONNECT_STRING", "localhost/freepdb1")
3636

3737
pw = os.environ.get("PYTHON_PASSWORD")
3838
if pw is None:

samples/tutorial/db_config_sys.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -----------------------------------------------------------------------------
2-
# Copyright (c) 2022, 2023, Oracle and/or its affiliates.
2+
# Copyright (c) 2022, 2025, Oracle and/or its affiliates.
33
#
44
# This software is dual-licensed to you under the Universal Permissive License
55
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -32,7 +32,7 @@
3232

3333
sysuser = os.environ.get("PYTHON_SYSUSER", "SYSTEM")
3434

35-
dsn = os.environ.get("PYTHON_CONNECT_STRING", "localhost/orclpdb")
35+
dsn = os.environ.get("PYTHON_CONNECT_STRING", "localhost/freepdb1")
3636

3737
syspw = os.environ.get("PYTHON_SYSPASSWORD")
3838
if syspw is None:

samples/tutorial/db_config_thick.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -----------------------------------------------------------------------------
2-
# Copyright (c) 2022, 2023, Oracle and/or its affiliates.
2+
# Copyright (c) 2022, 2025, Oracle and/or its affiliates.
33
#
44
# This software is dual-licensed to you under the Universal Permissive License
55
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -42,7 +42,7 @@
4242
# Client directory. Note the use of the raw string r"..." so backslashes can
4343
# be used as directory separators.
4444
if platform.system() == "Windows":
45-
instant_client_dir = r"C:\Oracle\instantclient_19_14"
45+
instant_client_dir = r"C:\Oracle\instantclient_23_7"
4646

4747
# On macOS set the directory to your Instant Client directory
4848
if platform.system() == "Darwin":
@@ -62,7 +62,7 @@
6262

6363
user = os.environ.get("PYTHON_USER", "pythondemo")
6464

65-
dsn = os.environ.get("PYTHON_CONNECT_STRING", "localhost/orclpdb")
65+
dsn = os.environ.get("PYTHON_CONNECT_STRING", "localhost/freepdb1")
6666

6767
pw = os.environ.get("PYTHON_PASSWORD")
6868
if pw is None:

samples/tutorial/drcp_query.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# -----------------------------------------------------------------------------
22
# drcp_query.py (Section 2.4 and 2.5)
3-
# Look at pool statistics of the DRCP Connection
3+
# Query DRCP pool statistics
44
# -----------------------------------------------------------------------------
55

66
# -----------------------------------------------------------------------------
7-
# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
7+
# Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
88
#
99
# This software is dual-licensed to you under the Universal Permissive License
1010
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
@@ -33,9 +33,7 @@
3333

3434
# default values
3535
PYTHON_SYS_USER = "SYSTEM"
36-
PYTHON_USER = "pythondemo"
37-
PYTHON_CONNECT_STRING = "localhost/orclpdb"
38-
PYTHON_DRCP_CONNECT_STRING = "localhost/orclpdb:pooled"
36+
PYTHON_DRCP_CONNECT_STRING = "localhost/free"
3937

4038
# dictionary containing all parameters; these are acquired as needed by the
4139
# methods below (which should be used instead of consulting this dictionary
@@ -63,7 +61,11 @@ def get_value(name, label, default_value=""):
6361

6462

6563
def get_main_user():
66-
return get_value("user", "Enter the DRCP User", PYTHON_SYS_USER)
64+
return get_value(
65+
"user",
66+
"Enter the privileged user with access to DRCP views",
67+
PYTHON_SYS_USER,
68+
)
6769

6870

6971
def get_main_password():
@@ -73,10 +75,10 @@ def get_main_password():
7375
def get_drcp_connect_string():
7476
connect_string = get_value(
7577
"DRCP_CONNECT_STRING",
76-
"Enter the DRCP Connect String",
78+
"Enter the connect string to access the DRCP views",
7779
PYTHON_DRCP_CONNECT_STRING,
7880
)
79-
return "%s/%s@%s" % (get_main_user(), get_main_password(), connect_string)
81+
return connect_string
8082

8183

8284
drcp_user = get_main_user()

samples/tutorial/json_insert.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# -----------------------------------------------------------------------------
2+
# json_insert.py (Section 8.1)
3+
# -----------------------------------------------------------------------------
4+
5+
# -----------------------------------------------------------------------------
6+
# Copyright (c) 2025, Oracle and/or its affiliates.
7+
#
8+
# This software is dual-licensed to you under the Universal Permissive License
9+
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
10+
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
11+
# either license.
12+
#
13+
# If you elect to accept the software under the Apache License, Version 2.0,
14+
# the following applies:
15+
#
16+
# Licensed under the Apache License, Version 2.0 (the "License");
17+
# you may not use this file except in compliance with the License.
18+
# You may obtain a copy of the License at
19+
#
20+
# https://www.apache.org/licenses/LICENSE-2.0
21+
#
22+
# Unless required by applicable law or agreed to in writing, software
23+
# distributed under the License is distributed on an "AS IS" BASIS,
24+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25+
# See the License for the specific language governing permissions and
26+
# limitations under the License.
27+
# -----------------------------------------------------------------------------
28+
29+
import oracledb
30+
import db_config
31+
32+
con = oracledb.connect(
33+
user=db_config.user, password=db_config.pw, dsn=db_config.dsn
34+
)
35+
cur = con.cursor()
36+
37+
# Insert JSON data
38+
data = dict(name="Rod", dept="Sales", location="Germany")
39+
inssql = "insert into jtab (id, json_data) values (:1, :2)"
40+
cur.setinputsizes(None, oracledb.DB_TYPE_JSON)
41+
cur.execute(inssql, [101, data])

samples/tutorial/pipelining.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# -----------------------------------------------------------------------------
2+
# pipelining.py (Section 18.1)
3+
# -----------------------------------------------------------------------------
4+
5+
# -----------------------------------------------------------------------------
6+
# Copyright (c) 2025, Oracle and/or its affiliates.
7+
#
8+
# This software is dual-licensed to you under the Universal Permissive License
9+
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
10+
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
11+
# either license.
12+
#
13+
# If you elect to accept the software under the Apache License, Version 2.0,
14+
# the following applies:
15+
#
16+
# Licensed under the Apache License, Version 2.0 (the "License");
17+
# you may not use this file except in compliance with the License.
18+
# You may obtain a copy of the License at
19+
#
20+
# https://www.apache.org/licenses/LICENSE-2.0
21+
#
22+
# Unless required by applicable law or agreed to in writing, software
23+
# distributed under the License is distributed on an "AS IS" BASIS,
24+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25+
# See the License for the specific language governing permissions and
26+
# limitations under the License.
27+
# -----------------------------------------------------------------------------
28+
29+
import asyncio
30+
import oracledb
31+
import db_config
32+
33+
34+
async def get_weather():
35+
return "Hot and sunny"
36+
37+
38+
async def get_location():
39+
return "Melbourne"
40+
41+
42+
async def main():
43+
con = await oracledb.connect_async(
44+
user=db_config.user, password=db_config.pw, dsn=db_config.dsn
45+
)
46+
47+
pipeline = oracledb.create_pipeline()
48+
pipeline.add_fetchone(
49+
"select ename, job from emp where empno = :en", [7839]
50+
)
51+
pipeline.add_fetchall("select dname from dept order by deptno")
52+
53+
# Run the pipeline and non-database operations concurrently.
54+
# Note although the database receives all the operations at the same time,
55+
# it will execute each operation sequentially. The local Python work
56+
# executes during the time the database is processing the queries.
57+
return_values = await asyncio.gather(
58+
get_weather(), get_location(), con.run_pipeline(pipeline)
59+
)
60+
61+
for r in return_values:
62+
if isinstance(r, list): # the pipeline return list
63+
for result in r:
64+
if result.rows:
65+
for row in result.rows:
66+
print(*row, sep="\t")
67+
else:
68+
print(r) # a local operation result
69+
70+
await con.close()
71+
72+
73+
asyncio.run(main())

0 commit comments

Comments
 (0)