Added a SODA section to the tutorial.

This commit is contained in:
Anthony Tuininga 2019-07-15 14:22:28 -06:00
parent e37e502724
commit b104d40016
4 changed files with 218 additions and 8 deletions

View File

@ -92,6 +92,12 @@
<li>10.1 Message passing with Oracle Advanced Queuing</li>
</ul>
</li>
<li><a href="#soda" >11. Simple Oracle Document Access (SODA)</a>
<ul>
<li>11.1 Inserting JSON Documents</li>
<li>11.2 Searching SODA Documents</li>
</ul>
</li>
</ul>
<li><a href="#summary" >Summary</a></li>
<li><a href="#primer" >Appendix: Python Primer</a></li>
@ -100,20 +106,23 @@
<h2><a name="preface">Preface</a></h2>
<p>If you are running this tutorial in your own environment, install the following required software:</p>
<p>If you are running this tutorial in your own environment, install the required software:</p>
<ol>
<li><a target="_blank" href="https://www.python.org/">Python</a> (3.6 preferred but 2.7 should work)</li>
<li>cx_Oracle (version 7.2 preferred but 6.3 or later should work, except for the section on Advanced Queuing which requires version 7.2 or later) and Oracle Instant Client Package - Basic (version 19.3 preferred but 18.3 or 12.2 should also work)
<li><p><a target="_blank" href="https://www.python.org/">Python</a>. Version 3.6 is preferred.</p></li>
<li><p>cx_Oracle version 7.2 and the Oracle Client libraries.</p>
<ul>
<li><a target="_blank" href="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-linux">Linux</a></li>
<li><a target="_blank" href="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-macos">macOS</a> - please note the special instructions for macOS in the link.</li>
<li><a target="_blank" href="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-windows">Windows</a></li>
</ul>
</li>
<li>Oracle <a target="_blank" href="http://www.oracle.com/technetwork/database/database-technologies/instant-client/overview/index.html">Instant Client Package - SQL*Plus</a>.</li>
<li><p>SQL*Plus such as from the Oracle <a target="_blank" href="http://www.oracle.com/technetwork/database/database-technologies/instant-client/overview/index.html">Instant Client SQL*Plus Package</a>.</p></li>
</ol>
<p>The Advanced Queuing section requires Oracle client 12.2 or later. The SODA section requires Oracle client 18.5, or later, and Oracle Database 18 or later.</p>
<p>To create the schema run:</p>
<pre>
@ -1661,6 +1670,9 @@ an Oracle object from the Python object values. The
<li><h3><a name="lobs">7. LOBs</a></h3>
<p>Oracle Database "LOB" long objects can be streamed using a LOB
locator, or worked with directly as strings or bytes.</p>
<ul>
<li>
<h4>7.1 Fetching a CLOB using a locator</h4>
@ -1694,8 +1706,8 @@ print("CLOB data:", clobdata)
</pre>
<p>This inserts some test string data and then fetches one
record into <code>clob</code>, which is a cx_Oracle LOB Object.
Methods on LOB include <code>size()</code> and
record into <code>clob</code>, which is a cx_Oracle character
LOB Object. Methods on LOB include <code>size()</code> and
<code>read()</code>.</p>
<p>To see the output, run the file:</p>
@ -1947,7 +1959,7 @@ invoke the parent methods to do the actual statement execution.</p>
<li><h3><a name="aq">10. Advanced Queuing</a></h3>
<ul>
<li><h4>10.1 Message passing with Oracle Advanced Queuing</h4></li>
<li><h4>10.1 Message passing with Oracle Advanced Queuing</h4>
<p>Review <code>aq.py</code>:</p>
@ -2074,6 +2086,114 @@ the <code>aq-dequeue.py</code>, <code>aq-enqueue.py</code> and
</ul>
</li>
</li>
<li><h3><a name="soda">11. Simple Oracle Document Access (SODA)</a></h3>
<p>Simple Oracle Document Access is a set of NoSQL-style APIs.
Documents can be inserted, queried, and retrieved from Oracle
Database. By default, documents are JSON strings. SODA APIs
exist in many languages.</p>
<ul>
<li><h4>11.1 Inserting JSON Documents</h4>
<p>Review <code>soda.py</code>:</p>
<pre>
import cx_Oracle
import db_config
con = cx_Oracle.connect(db_config.user, db_config.pw, db_config.dsn)
soda = con.getSodaDatabase()
collection = soda.createCollection("friends")
content = {'name': 'Jared', 'age': 35, 'address': {'city': 'Melbourne'}}
doc = collection.insertOneAndGet(content)
key = doc.key
doc = collection.find().key(key).getOne()
content = doc.getContent()
print('Retrieved SODA document dictionary is:')
print(content)
</pre>
<p><code>soda.createCollection()</code> will create a new
collection, or open an existing collection, if the name is
already in use.</p>
<p><code>insertOneAndGet()</code> inserts the content of a
document into the database and returns a SODA Document Object.
This allows access to meta data such as the document key. By
default, document keys are automatically generated.</p>
<p>The <code>find()</code> method is used to begin an operation
that will act upon documents in the collection.</p>
<p><code>content</code> is a dictionary. You can also get a JSON string
by calling <code>doc.getContentAsString()</code>.</p>
<p>Run the file:</p>
<pre><strong>python soda.py</strong></pre>
<p>The output shows the content of the new document.</p>
</li>
<li><h4>11.2 Searching SODA Documents</h4>
<p>Extend <code>soda.py</code> to insert some more documents and
perform a find filter operation:</p>
<pre>
myDocs = [
{'name': 'Gerald', 'age': 21, 'address': {'city': 'London'}},
{'name': 'David', 'age': 28, 'address': {'city': 'Melbourne'}},
{'name': 'Shawn', 'age': 20, 'address': {'city': 'San Francisco'}}
]
collection.insertMany(myDocs)
filterSpec = { "address.city": "Melbourne" }
myDocuments = collection.find().filter(filterSpec).getDocuments()
print('Melbourne people:')
for doc in myDocuments:
print(doc.getContent()["name"])
</pre>
<p>Run the script again:</p>
<pre><strong>python soda.py</strong></pre>
<p>The find operation filters the collection and returns
documents where the city is Melbourne. Note the
<code>insertMany()</code> method is currently in preview.</p>
<p>SODA supports query by example (QBE) with an extensive set of
operators. Extend <code>soda.py</code> with a QBE to find
documents where the age is less than 25:</p>
<pre>
filterSpec = {'age': {'$lt': 25}}
myDocuments = collection.find().filter(filterSpec).getDocuments()
print('Young people:')
for doc in myDocuments:
print(doc.getContent()["name"])
</pre>
<p>Running the script displays the names.</p>
</li>
</ul>
</li>
</ol>
<h2><a name="summary">Summary</a></h2>
@ -2307,7 +2427,7 @@ import sys</pre>
<div class="footer"></div>
<table border="0" cellpadding="10" cellspacing="0" width="100%">
<tbody><tr>
<td align="right" width="54%">Copyright &copy; 2017, Oracle and/or its affiliates. All rights reserved</td>
<td align="right" width="54%">Copyright &copy; 2017, 2019, Oracle and/or its affiliates. All rights reserved</td>
</tr>
<tr><td colspan="2"></td></tr>
</tbody>

28
samples/tutorial/soda.py Normal file
View File

@ -0,0 +1,28 @@
#------------------------------------------------------------------------------
# soda.py (Section 11.1)
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
#------------------------------------------------------------------------------
from __future__ import print_function
import cx_Oracle
import db_config
con = cx_Oracle.connect(db_config.user, db_config.pw, db_config.dsn)
soda = con.getSodaDatabase()
collection = soda.createCollection("friends")
content = {'name': 'Jared', 'age': 35, 'address': {'city': 'Melbourne'}}
doc = collection.insertOneAndGet(content)
key = doc.key
doc = collection.find().key(key).getOne()
content = doc.getContent()
print('Retrieved SODA document dictionary is:')
print(content)

View File

@ -0,0 +1,49 @@
#------------------------------------------------------------------------------
# soda.py (Section 11.2)
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
#------------------------------------------------------------------------------
from __future__ import print_function
import cx_Oracle
import db_config
con = cx_Oracle.connect(db_config.user, db_config.pw, db_config.dsn)
soda = con.getSodaDatabase()
collection = soda.createCollection("friends")
content = {'name': 'Jared', 'age': 35, 'address': {'city': 'Melbourne'}}
doc = collection.insertOneAndGet(content)
key = doc.key
doc = collection.find().key(key).getOne()
content = doc.getContent()
print('Retrieved SODA document dictionary is:')
print(content)
myDocs = [
{'name': 'Gerald', 'age': 21, 'address': {'city': 'London'}},
{'name': 'David', 'age': 28, 'address': {'city': 'Melbourne'}},
{'name': 'Shawn', 'age': 20, 'address': {'city': 'San Francisco'}}
]
collection.insertMany(myDocs)
filterSpec = { "address.city": "Melbourne" }
myDocuments = collection.find().filter(filterSpec).getDocuments()
print('Melbourne people:')
for doc in myDocuments:
print(doc.getContent()["name"])
filterSpec = {'age': {'$lt': 25}}
myDocuments = collection.find().filter(filterSpec).getDocuments()
print('Young people:')
for doc in myDocuments:
print(doc.getContent()["name"])

View File

@ -38,6 +38,19 @@ to &main_user;
grant execute on dbms_aqadm to &main_user;
grant execute on dbms_lock to &main_user;
begin
for r in
( select role
from dba_roles
where role in ('SODA_APP')
) loop
execute immediate 'grant ' || r.role || ' to &main_user';
end loop;
end;
/
create table &main_user..testclobs (
id number not null,
myclob clob not null