Skip to content

Commit 4ebd8c9

Browse files
Improvement of samples.
1 parent 72a2463 commit 4ebd8c9

10 files changed

+589
-22
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ doc/build
88
src/oracledb/*.c
99
tests/ext/config.ini
1010
.ipynb_checkpoints/
11+
samples/sample.csv

samples/json_duality.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,12 @@
4848
dsn=sample_env.get_connect_string(),
4949
)
5050

51+
# this script only works with Oracle Database 23.5 or later
52+
if sample_env.get_server_version() < (23, 5):
53+
sys.exit("This example requires Oracle Database 23.5 or later")
54+
5155
if not connection.thin:
5256
client_version = oracledb.clientversion()[0]
53-
db_version = int(connection.version.split(".")[0])
54-
55-
# this script only works with Oracle Database 23ai
56-
if db_version < 23:
57-
sys.exit("This example requires Oracle Database 23 or later. ")
5857

5958
with connection.cursor() as cursor:
6059

samples/json_duality_async.py

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# -----------------------------------------------------------------------------
2+
# Copyright (c) 2024, Oracle and/or its affiliates.
3+
#
4+
# This software is dual-licensed to you under the Universal Permissive License
5+
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
6+
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
7+
# either license.
8+
#
9+
# If you elect to accept the software under the Apache License, Version 2.0,
10+
# the following applies:
11+
#
12+
# Licensed under the Apache License, Version 2.0 (the "License");
13+
# you may not use this file except in compliance with the License.
14+
# You may obtain a copy of the License at
15+
#
16+
# https://www.apache.org/licenses/LICENSE-2.0
17+
#
18+
# Unless required by applicable law or agreed to in writing, software
19+
# distributed under the License is distributed on an "AS IS" BASIS,
20+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21+
# See the License for the specific language governing permissions and
22+
# limitations under the License.
23+
# -----------------------------------------------------------------------------
24+
25+
# -----------------------------------------------------------------------------
26+
# json_duality_async.py
27+
#
28+
# An asynchronous version of json_duality.py
29+
#
30+
# Demonstrates Oracle Database 23ai JSON-Relational Duality Views.
31+
#
32+
# Reference: https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=ADJSN
33+
# -----------------------------------------------------------------------------
34+
35+
import asyncio
36+
import sys
37+
38+
import oracledb
39+
import sample_env
40+
41+
42+
async def main():
43+
connection = await oracledb.connect_async(
44+
user=sample_env.get_main_user(),
45+
password=sample_env.get_main_password(),
46+
dsn=sample_env.get_connect_string(),
47+
)
48+
49+
# this script only works with Oracle Database 23.5 or later
50+
if sample_env.get_server_version() < (23, 5):
51+
sys.exit("This example requires Oracle Database 23.5 or later")
52+
53+
with connection.cursor() as cursor:
54+
55+
# Create a JSON-Relational Duality View over the SampleJRDVAuthorTab
56+
# and SampleJRDVBookTab tables
57+
sql = """
58+
create or replace json relational duality view BookDV as
59+
SampleJRDVBookTab @insert @update @delete
60+
{
61+
_id: BookId,
62+
book_title: BookTitle,
63+
author: SampleJRDVAuthorTab @insert @update
64+
{
65+
author_id: AuthorId,
66+
author_name: AuthorName
67+
}
68+
}"""
69+
await cursor.execute(sql)
70+
71+
with connection.cursor() as cursor:
72+
73+
# Insert a new book and author into the Duality View and show the
74+
# resulting new records in the relational tables
75+
data = dict(
76+
_id=101,
77+
book_title="Cooking at Home",
78+
author=dict(author_id=201, author_name="Dave Smith"),
79+
)
80+
inssql = "insert into BookDV values (:1)"
81+
cursor.setinputsizes(oracledb.DB_TYPE_JSON)
82+
await cursor.execute(inssql, [data])
83+
84+
print("Authors in the relational table:")
85+
await cursor.execute(
86+
"select * from SampleJRDVAuthorTab order by AuthorId"
87+
)
88+
async for row in cursor:
89+
print(row)
90+
91+
print("\nBooks in the relational table:")
92+
await cursor.execute("select * from SampleJRDVBookTab order by BookId")
93+
async for row in cursor:
94+
print(row)
95+
96+
# Select from the duality view
97+
98+
with connection.cursor() as cursor:
99+
100+
print("\nDuality view query for an author's books:")
101+
sql = """select b.data.book_title, b.data.author.author_name
102+
from BookDV b
103+
where b.data.author.author_id = :1"""
104+
await cursor.execute(sql, [1])
105+
async for r in cursor:
106+
print(r)
107+
108+
print("\nDuality view query of all records:")
109+
sql = """select data from BookDV"""
110+
await cursor.execute(sql)
111+
async for (j,) in cursor:
112+
print(j)
113+
114+
115+
asyncio.run(main())

samples/plsql_rowtype_async.py

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# -----------------------------------------------------------------------------
2+
# Copyright (c) 2024, Oracle and/or its affiliates.
3+
#
4+
# This software is dual-licensed to you under the Universal Permissive License
5+
# (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
6+
# 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
7+
# either license.
8+
#
9+
# If you elect to accept the software under the Apache License, Version 2.0,
10+
# the following applies:
11+
#
12+
# Licensed under the Apache License, Version 2.0 (the "License");
13+
# you may not use this file except in compliance with the License.
14+
# You may obtain a copy of the License at
15+
#
16+
# https://www.apache.org/licenses/LICENSE-2.0
17+
#
18+
# Unless required by applicable law or agreed to in writing, software
19+
# distributed under the License is distributed on an "AS IS" BASIS,
20+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21+
# See the License for the specific language governing permissions and
22+
# limitations under the License.
23+
# -----------------------------------------------------------------------------
24+
25+
# -----------------------------------------------------------------------------
26+
# plsql_rowtype_async.py
27+
#
28+
# An asynchronous version of plsql_rowtype.py
29+
#
30+
# Demonstrates how to use a PL/SQL %ROWTYPE attribute
31+
# -----------------------------------------------------------------------------
32+
33+
import asyncio
34+
35+
import oracledb
36+
import sample_env
37+
38+
39+
async def main():
40+
connection = await oracledb.connect_async(
41+
user=sample_env.get_main_user(),
42+
password=sample_env.get_main_password(),
43+
dsn=sample_env.get_connect_string(),
44+
)
45+
46+
with connection.cursor() as cursor:
47+
48+
await cursor.execute(
49+
"""
50+
begin
51+
begin
52+
execute immediate 'drop table RTSampleTable';
53+
exception
54+
when others then
55+
if sqlcode <> -942 then
56+
raise;
57+
end if;
58+
end;
59+
60+
execute immediate 'create table RTSampleTable (
61+
city varchar2(10))';
62+
63+
execute immediate
64+
'insert into RTSampleTable values (''London'')';
65+
66+
commit;
67+
68+
end;
69+
"""
70+
)
71+
72+
await cursor.execute(
73+
"""
74+
create or replace function TestFuncOUT return RTSampleTable%rowtype
75+
as
76+
r RTSampleTable%rowtype;
77+
begin
78+
select * into r from RTSampleTable where rownum < 2 order by 1;
79+
return r;
80+
end;"""
81+
)
82+
if cursor.warning:
83+
print(cursor.warning)
84+
85+
await cursor.execute(
86+
"""
87+
create or replace procedure TestProcIN(
88+
r in RTSampleTable%rowtype, city out varchar2) as
89+
begin
90+
city := r.city;
91+
end;"""
92+
)
93+
if cursor.warning:
94+
print(cursor.warning)
95+
96+
# Getting a %ROWTYPE from PL/SQL returns a python-oracledb DbObject
97+
# record
98+
99+
rt = await connection.gettype("RTSAMPLETABLE%ROWTYPE")
100+
r = await cursor.callfunc("TESTFUNCOUT", rt)
101+
print("1. City is:", r.CITY)
102+
# dump_object(r) # This is defined in object_dump.py
103+
104+
# An equivalent record can be directly constructed
105+
106+
obj = rt.newobject()
107+
obj.CITY = "My Town"
108+
109+
# Passing a record to a %ROWTYPE parameter
110+
111+
c = cursor.var(oracledb.DB_TYPE_VARCHAR)
112+
await cursor.callproc("TESTPROCIN", [r, c])
113+
print("2. City is:", c.getvalue())
114+
115+
await cursor.callproc("TESTPROCIN", [obj, c])
116+
print("3. City is:", c.getvalue())
117+
118+
119+
asyncio.run(main())

samples/session_callback.py

+21-14
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@
4747
#
4848
# python session_callback.py
4949
#
50-
# 4. Run this script and experiment sending web requests. For example
50+
# 4. Run this script and experiment sending web requests. For example to
5151
# send 20 requests with a concurrency of 4:
52-
# ab -n 20 -c 4 http://127.0.0.1:7000/
52+
# ab -n 20 -c 4 http://127.0.0.1:8080/
5353
#
5454
# The application console output will show that queries are executed multiple
5555
# times for each session created, but the initialization function for each
@@ -65,7 +65,7 @@
6565
import sample_env
6666

6767
# Port to listen on
68-
port = int(os.environ.get("PORT", "8080"))
68+
PORT = int(os.environ.get("PORT", "8080"))
6969

7070
# determine whether to use python-oracledb thin mode or thick mode
7171
if not sample_env.get_is_thin():
@@ -76,14 +76,19 @@
7676

7777
# init_session(): The session callback. The requested_tag parameter is not used
7878
# in this example.
79-
def init_session(conn, requested_tag):
79+
def init_session(connection, requested_tag):
8080
# Your session initialization code would be here. This example just
8181
# queries the session id to show that the callback is invoked once per
8282
# session.
83-
for (r,) in conn.cursor().execute(
84-
"SELECT SYS_CONTEXT('USERENV','SID') FROM DUAL"
85-
):
86-
print(f"init_session() invoked for session {r}")
83+
with connection.cursor() as cursor:
84+
cursor.execute(
85+
"""
86+
select current_timestamp, sid || '-' || serial#
87+
from v$session
88+
where sid = sys_context('userenv','sid')"""
89+
)
90+
t, s = cursor.fetchone()
91+
print(f"init_session() at time {t} was invoked for session {s}")
8792

8893

8994
# start_pool(): starts the connection pool with a session callback defined
@@ -110,10 +115,12 @@ def start_pool():
110115
def index():
111116
with pool.acquire() as connection:
112117
with connection.cursor() as cursor:
113-
sql = """
114-
SELECT CURRENT_TIMESTAMP, SYS_CONTEXT('USERENV','SID')
115-
FROM DUAL"""
116-
cursor.execute(sql)
118+
cursor.execute(
119+
"""
120+
select current_timestamp, sid || '-' || serial#
121+
from v$session
122+
where sid = sys_context('userenv','sid')"""
123+
)
117124
t, s = cursor.fetchone()
118125
r = f"Query at time {t} used session {s}"
119126
print(r)
@@ -126,8 +133,8 @@ def index():
126133
# Start a pool of connections
127134
pool = start_pool()
128135

129-
m = f"\nTry loading http://127.0.0.1:{port}/ in a browser\n"
136+
m = f"\nTry loading http://127.0.0.1:{PORT}/ in a browser\n"
130137
sys.modules["flask.cli"].show_server_banner = lambda *x: print(m)
131138

132139
# Start a webserver
133-
app.run(port=port)
140+
app.run(port=PORT)

samples/soda_json_duality.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
# this script is currently only supported in python-oracledb thick mode
4343
oracledb.init_oracle_client(lib_dir=sample_env.get_oracle_client())
4444

45-
# this script only works with Oracle Database & Client 23.4 or later
46-
if sample_env.get_server_version() < (23, 4):
47-
sys.exit("This example requires Oracle Database 23.4 or later.")
45+
# this script only works with Oracle Database 23.5 & Client 23.4 or later
46+
if sample_env.get_server_version() < (23, 5):
47+
sys.exit("This example requires Oracle Database 23.5 or later")
4848
if oracledb.clientversion()[:2] < (23, 4):
4949
sys.exit("This example requires Oracle Client 23.4 or later")
5050

0 commit comments

Comments
 (0)