Skip to content

Commit 0e0032c

Browse files
authored
Merge pull request #706 from oracle-devrel/json-track
json-workshop updates
2 parents 936c3e8 + fa6da11 commit 0e0032c

File tree

11 files changed

+1231
-0
lines changed

11 files changed

+1231
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Copyright (c) 2023 Oracle and/or its affiliates.
2+
3+
The Universal Permissive License (UPL), Version 1.0
4+
5+
Subject to the condition set forth below, permission is hereby granted to any
6+
person obtaining a copy of this software, associated documentation and/or data
7+
(collectively the "Software"), free of charge and under any and all copyright
8+
rights in the Software, and any and all patent rights owned or freely
9+
licensable by each licensor hereunder covering either (i) the unmodified
10+
Software as contributed to or provided by such licensor, or (ii) the Larger
11+
Works (as defined below), to deal in both
12+
13+
(a) the Software, and
14+
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
15+
one is included with the Software (each a "Larger Work" to which the Software
16+
is contributed by such licensors),
17+
18+
without restriction, including without limitation the rights to copy, create
19+
derivative works of, display, perform, and distribute the Software and make,
20+
use, sell, offer for sale, import, export, have made, and have sold the
21+
Software and the Larger Work(s), and to sublicense the foregoing rights on
22+
either these or other terms.
23+
24+
This license is subject to the following condition:
25+
The above copyright notice and either this complete permission notice or at
26+
a minimum a reference to the UPL must be included in all copies or
27+
substantial portions of the Software.
28+
29+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35+
SOFTWARE.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Python developer track for Oracle JSON and Duality Views
2+
3+
This workshop will show how to start developing with Python using Oracle JSON and the latest feature Duality Views.
4+
5+
Reviewed: 15.01.2024
6+
7+
# When to use this asset?
8+
9+
If you are interested in learning how to start developing with Oracle JSON and how to work with Oracle Duality Views, this workshop is for you. This workshop assumes no previous knowledge of Oracle or Python.
10+
11+
# How to use this asset?
12+
13+
The workshop has 9 different exercises. You must run all the exercises as they are dependent. These are the exercises covered:
14+
15+
1. Prepare environment. Using Oracle 23c Developer Free.
16+
2. First steps with Python and Oracle.
17+
3. CRUD operations for Python and JSON.
18+
4. Query by Example. Running some queries.
19+
5. Indexing.
20+
6. Graphical Interface for JSON. Using Database Actions.
21+
7. Data Modeling: SODA, Hybrid and Duality Views.
22+
8. Running SQL over JSON data.
23+
9. MongoDB API over Duality Views.
24+
25+
All these exercises are explained individually under the files folder. However, each of the exercises is covered in a blog. If you want to read in detail this exercises, you can find them here: [Python Developer Track for Oracle JSON and Duality Views](https://dev.to/javierdelatorre/python-developer-track-for-oracle-json-and-duality-views-2b9h)
26+
27+
28+
# License
29+
30+
Copyright (c) 2023 Oracle and/or its affiliates.
31+
32+
Licensed under the Universal Permissive License (UPL), Version 1.0.
33+
34+
See [LICENSE](https://github.com/oracle-devrel/technology-engineering/blob/main/LICENSE) for more details.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
========= Provision a OCI VM ===============
2+
3+
For this workshop we are going to use a Oracle Cloud VM with Oracle Linux 8.
4+
5+
=========== Install and configure 23c free ========
6+
7+
Obtain all the information for Oracle 23c Developer Free here: https://www.oracle.com/uk/database/free/get-started/
8+
9+
1. Install Oracle 23c Developer free as root:
10+
11+
sudo su
12+
wget https://yum.oracle.com/repo/OracleLinux/OL8/developer/x86_64/getPackage/oracle-database-preinstall-23c-1.0-0.5.el8.x86_64.rpm
13+
wget https://download.oracle.com/otn-pub/otn_software/db-free/oracle-database-free-23c-1.0-1.el8.x86_64.rpm
14+
yum -y localinstall oracle-database*
15+
16+
2.- Configure Oracle 23c free
17+
18+
/etc/init.d/oracle-free-23c configure
19+
20+
3.- Enable firewall and automatic start of 23c Database.
21+
22+
systemctl enable oracle-free-23c
23+
firewall-cmd --permanent --add-port=1521/tcp
24+
firewall-cmd --reload
25+
26+
=========Install python =========
27+
28+
-- We need python 3.7 or higher. We install python3.11
29+
python --version
30+
yum install python3.11
31+
32+
--select python 3.11 as default, should be selection 2
33+
update-alternatives --config python3
34+
35+
-- Install pip and Oracle Driver for python: oracledb
36+
yum install python3.11-pip
37+
python -m pip install oracledb --upgrade
38+
exit
39+
40+
4.- Set environment variables to use sqlplus
41+
42+
echo 'export ORACLE_HOME=/opt/oracle/product/23c/dbhomeFree' >> .bashrc
43+
echo 'export PATH=$ORACLE_HOME/bin:$PATH' >> .bashrc
44+
. .bashrc
45+
46+
========== Create new user for 23c ==============
47+
=== PLEASE CHANGE YOUR_PASSWORD TO A REAL PASSWORD! ===
48+
49+
sqlplus sys/YOUR_PASSWORD@localhost:1521/FREEPDB1 as sysdba
50+
create user myapp identified by YOUR_PASSWORD;
51+
grant db_developer_role to myapp;
52+
alter user myapp quota unlimited on users;
53+
exit;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import oracledb
2+
3+
#thick mode for SODA
4+
oracledb.init_oracle_client()
5+
6+
#connection details
7+
# === PLEASE CHANGE YOUR_PASSWORD TO A REAL PASSWORD! ===
8+
connection = oracledb.connect(user="myapp",password="YOUR_PASSWORD",dsn="localhost:1521/FREEPDB1")
9+
10+
#connect, create and list collections
11+
soda = connection.getSodaDatabase()
12+
collection1 =soda.createCollection("my_first_collection")
13+
collection2= soda.createCollection("my_second_collection")
14+
list=soda.getCollectionNames()
15+
print(list)
16+
17+
#delete one collection
18+
collection2.drop()
19+
20+
list=soda.getCollectionNames()
21+
print(list)
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
import oracledb
2+
3+
4+
#connect with thick-client
5+
oracledb.init_oracle_client()
6+
7+
#=== PLEASE CHANGE YOUR_PASSWORD TO A REAL PASSWORD! ===
8+
connection = oracledb.connect(user="myapp",
9+
password="YOUR_PASSWORD",
10+
dsn="localhost:1521/FREEPDB1")
11+
12+
#auto commit
13+
connection.autocommit = True
14+
15+
#Create new collection for hotel reservations
16+
soda = connection.getSodaDatabase()
17+
collection = soda.createCollection("hotel_reservations")
18+
collection = soda.openCollection("hotel_reservations")
19+
20+
#Task 1: insertDocument
21+
collection.insertOne(
22+
{
23+
"reservation_id": "1",
24+
"hotel_id": "123",
25+
"room_id": "105",
26+
"checkin_date": "2023-06-03",
27+
"checkout_date": "2023-06-07",
28+
"num_adults": 2,
29+
"num_children": 0,
30+
"guest_name": {
31+
"first_name": "Maria",
32+
"last_name": "Rodriguez"
33+
},
34+
"guest_contact_info": {
35+
"email": "[email protected]",
36+
"phone": "777-4231",
37+
"address": {
38+
"city": "Paris",
39+
"country": "France"
40+
}
41+
},
42+
"total_cost": 650.00,
43+
"payment_status": "paid"
44+
})
45+
46+
#Task2: Insert one and get Key
47+
content = {
48+
"reservation_id": "2",
49+
"hotel_id": "123",
50+
"room_id": "315",
51+
"checkin_date": "2023-06-15",
52+
"checkout_date": "2023-06-17",
53+
"num_adults": 1,
54+
"num_children": 0,
55+
"guest_name": {
56+
"first_name": "Ethan",
57+
"last_name": "Lee"
58+
},
59+
"guest_contact_info": {
60+
"email": "[email protected]",
61+
"phone": "123-8106",
62+
"address": {
63+
"city": "Madrid",
64+
"country": "Spain"
65+
}
66+
},
67+
"total_cost": 350.00,
68+
"payment_status": "paid"
69+
}
70+
71+
document = collection.insertOneAndGet(content)
72+
key = document.key
73+
print('\n The key of the document is: ', key)
74+
75+
76+
77+
#Task 3: fetch by key
78+
document = collection.find().key(key).getOne()
79+
content = document.getContent()
80+
print('\n The document is:')
81+
print(content)
82+
83+
#Task 4: insertMany
84+
85+
all_documents=[
86+
{
87+
"reservation_id": "3",
88+
"hotel_id": "123",
89+
"room_id": "207",
90+
"checkin_date": "2023-06-25",
91+
"checkout_date": "2023-06-30",
92+
"num_adults": 2,
93+
"num_children": 0,
94+
"guest_name": {
95+
"first_name": "Olivia",
96+
"last_name": "Johnson"
97+
},
98+
"guest_contact_info": {
99+
"email": "[email protected]",
100+
"phone": "987-1890",
101+
"address": {
102+
"city": "Barcelona",
103+
"country": "Spain"
104+
}
105+
},
106+
"total_cost": 932.00,
107+
"payment_status": "pending"
108+
}
109+
,
110+
111+
{
112+
"reservation_id": "4",
113+
"hotel_id": "123",
114+
"room_id": "222",
115+
"checkin_date": "2023-06-07",
116+
"checkout_date": "2023-06-17",
117+
"num_adults": 2,
118+
"num_children": 0,
119+
"guest_name": {
120+
"first_name": "Liam",
121+
"last_name": "Patel"
122+
},
123+
"guest_contact_info": {
124+
"email": "[email protected]",
125+
"phone": "123-8106",
126+
"address": {
127+
"city": "Malaga",
128+
"country": "Spain"
129+
}
130+
},
131+
"total_cost": 350.00,
132+
"payment_status": "paid"
133+
}
134+
135+
,
136+
137+
{
138+
"reservation_id": "5",
139+
"hotel_id": "123",
140+
"room_id": "101",
141+
"checkin_date": "2023-06-01",
142+
"checkout_date": "2023-06-05",
143+
"num_adults": 2,
144+
"num_children": 1,
145+
"guest_name": {
146+
"first_name": "John",
147+
"last_name": "Smith"
148+
},
149+
"guest_contact_info": {
150+
"email": "[email protected]",
151+
"phone": "555-1234",
152+
"address": {
153+
"city": "Lyon",
154+
"country": "France"
155+
}
156+
},
157+
"additional_requests": [
158+
{
159+
"type": "extra_bed",
160+
"quantity": 1
161+
},
162+
{
163+
"type": "late_checkout",
164+
"details": "Please arrange for a 2pm checkout"
165+
}
166+
],
167+
"total_cost": 800.00,
168+
"payment_status": "paid"
169+
}
170+
,
171+
{
172+
"reservation_id": "6",
173+
"hotel_id": "123",
174+
"room_id": "305",
175+
"checkin_date": "2023-06-04",
176+
"checkout_date": "2023-06-20",
177+
"num_adults": 2,
178+
"num_children": 0,
179+
"guest_name": {
180+
"first_name": "Marcus",
181+
"last_name": "Wong"
182+
},
183+
"guest_contact_info": {
184+
"email": "[email protected]",
185+
"phone": "123-1234",
186+
"address": {
187+
"city": "Nice",
188+
"country": "France"
189+
}
190+
},
191+
"total_cost": 1350.00,
192+
"payment_status": "cancelled"
193+
}
194+
195+
]
196+
result_docs = collection.insertManyAndGet(all_documents)
197+
198+
#Task5: count all documents
199+
200+
total = collection.find().count()
201+
print('\n My hotel has', total, 'reservations')
202+
203+
204+
#Task 6: Find customers who didn't pay
205+
documents = collection.find().filter({'payment_status': "pending"}).getDocuments()
206+
print('\n Customers who didn\'t pay:')
207+
for d in documents:
208+
content = d.getContent()
209+
print(content["guest_contact_info"])
210+
211+
212+
#Task 7: Replace pending to paid
213+
214+
new_content = {
215+
"reservation_id": "3",
216+
"hotel_id": "123",
217+
"room_id": "207",
218+
"checkin_date": "2023-06-25",
219+
"checkout_date": "2023-06-30",
220+
"num_adults": 2,
221+
"num_children": 0,
222+
"guest_name": {
223+
"first_name": "Olivia",
224+
"last_name": "Johnson"
225+
},
226+
"guest_contact_info": {
227+
"email": "[email protected]",
228+
"phone": "987-1890",
229+
"address": {
230+
"city": "Barcelona",
231+
"country": "Spain"
232+
}
233+
},
234+
"total_cost": 932.00,
235+
"payment_status": "paid"
236+
237+
}
238+
239+
to_modify_doc = collection.find().filter({'payment_status': "pending"}).getOne()
240+
key=to_modify_doc.key
241+
collection.find().key(key).replaceOne(new_content)
242+
243+
#Task 8: delete a cancelled reservation
244+
245+
deleted = collection.find().filter({'payment_status': "cancelled"}).remove()
246+
print('\n Deleted', deleted, 'documents')

0 commit comments

Comments
 (0)