Skip to content

Commit b7b0ccd

Browse files
committed
Add more to ORM jupyter notebook
1 parent fe49cd1 commit b7b0ccd

File tree

1 file changed

+126
-11
lines changed

1 file changed

+126
-11
lines changed

python/jupyter_notebook/CipherStash-Getting-Started.ipynb

Lines changed: 126 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"source": [
88
"# Getting Started with CipherStash and Jupyter Notebook\n",
99
"\n",
10-
"This notebook describes how to get started with CipherStash using Python3, Jupyter Notebook, and psycopg2.\n",
10+
"This notebook describes how to get started with CipherStash using Python3, Jupyter Notebook, psycopg2 and SQLAlchemy.and\n",
1111
"\n",
1212
"## Prerequisites\n",
1313
"\n",
@@ -784,12 +784,31 @@
784784
" \"UPDATE examples SET encrypted_utf8_str = %s WHERE id = %s\",\n",
785785
" (CsText(\"UPDATED TEXT\", \"examples\", \"encrypted_utf8_str\").to_db_format(), record_id) # Replace 'column_name' and 'new_value' with actual column and value\n",
786786
")\n",
787-
"\n",
788787
"cur.execute(\"SELECT * FROM examples WHERE id = %s\", (record_id,))\n",
789788
"found = cur.fetchall()[0]\n",
790789
"print(f\"Updated row: {CsRow(found).row}\")"
791790
]
792791
},
792+
{
793+
"cell_type": "markdown",
794+
"id": "e24df4fc-11c6-489e-8b6f-45faa47bab8e",
795+
"metadata": {},
796+
"source": [
797+
"### Roll back\n",
798+
"\n",
799+
"Free up the database connection so we can delete the table contentsup by rolling back before going to the next section:"
800+
]
801+
},
802+
{
803+
"cell_type": "code",
804+
"execution_count": null,
805+
"id": "f9b74fa1-430e-49d2-868c-5acff124ceb4",
806+
"metadata": {},
807+
"outputs": [],
808+
"source": [
809+
"conn.rollback()"
810+
]
811+
},
793812
{
794813
"cell_type": "markdown",
795814
"id": "bf498c2e-00fa-4746-85b3-c4008b55003d",
@@ -813,21 +832,59 @@
813832
"outputs": [],
814833
"source": [
815834
"from cs_models import *\n",
835+
"from datetime import date\n",
816836
"\n",
817837
"# Creating engine. Optionally add echo=True to see the SQL statetments dumped to stdout\n",
818838
"engine = create_engine('postgresql://postgres:postgres@localhost:6432/cipherstash_getting_started')\n",
819839
"Session = sessionmaker(bind=engine)\n",
820840
"session = Session()\n",
821841
"\n",
822-
"BaseModel.metadata.create_all(engine) # Create table for models if it's not created yet\n",
842+
"BaseModel.metadata.create_all(engine) # Create table for models if it's not created yetbelow and\n",
823843
"\n",
824844
"session.query(Example).delete() # Clear data if there is any from previous runs\n",
845+
"ex = Example(e_utf8_str = \"example record 1\", e_jsonb = json.dumps({'a': {'b': 1}}), e_int = 42, e_float = 3.14, e_date = date.today(), e_bool=False)\n",
825846
"\n",
826-
"ex = Example(utf8_str = \"example record 1\", jsonb = json.dumps({'a': {'b': 1}}))\n",
847+
"session.add(ex)\n",
848+
"session.commit()\n",
849+
"\n",
850+
"ex = Example(e_utf8_str = \"example record 2\", e_jsonb = json.dumps({'a': {'c': 2}}), e_int = 43, e_float = 1.41, e_date = date.today(), e_bool=True)\n",
851+
"session.add(ex)\n",
852+
"session.commit()\n",
827853
"\n",
854+
"ex3 = Example(e_utf8_str = \"example record 1\", e_jsonb = json.dumps({'a': {'b': 1}}), e_int = 44, e_float = 2.718, e_date = date.today(), e_bool=True)\n",
828855
"session.add(ex)\n",
829856
"session.commit()\n",
830857
"\n",
858+
"'''\n",
859+
"ex1 = Example(\n",
860+
" e_utf8_str = \"example record 1\",\n",
861+
" e_jsonb = json.dumps({'a': {'b': 1}}),\n",
862+
" e_int = 42,\n",
863+
" e_float = 3.14,\n",
864+
" e_date = date.today(),\n",
865+
" e_bool=False)\n",
866+
"\n",
867+
"ex2 = Example(\n",
868+
" e_utf8_str = \"example record 2\",\n",
869+
" e_jsonb = json.dumps({'a': {'c': 2}}),\n",
870+
" e_int = 44,\n",
871+
" e_float = 1.41,\n",
872+
" e_date = date.today(),\n",
873+
" e_bool=True)\n",
874+
"\n",
875+
"ex3 = Example(\n",
876+
" e_utf8_str = \"example record 1\",\n",
877+
" e_jsonb = json.dumps({'a': {'b': 1}}),\n",
878+
" e_int = 44,\n",
879+
" e_float = 2.718,\n",
880+
" e_date = date.today(),\n",
881+
" e_bool=True)\n",
882+
"\n",
883+
"session.add(ex1)\n",
884+
"session.add(ex2)\n",
885+
"session.add(ex3)\n",
886+
"session.commit()\n",
887+
"'''\n",
831888
"# After the commit above, the records are visible outside of this session\n",
832889
"\n",
833890
"print(\"Example data creation done\")"
@@ -877,6 +934,60 @@
877934
"results[0].encrypted_utf8_str"
878935
]
879936
},
937+
{
938+
"cell_type": "markdown",
939+
"id": "1c493bdf-25fa-49ab-a5ab-87e0fbf595e5",
940+
"metadata": {},
941+
"source": [
942+
"### Querying by partial match\n",
943+
"\n",
944+
"Partial matching can also performed with SQLAlchemy:"
945+
]
946+
},
947+
{
948+
"cell_type": "code",
949+
"execution_count": null,
950+
"id": "2cfd86e9-70d2-420b-b56f-11744d5ae4bf",
951+
"metadata": {},
952+
"outputs": [],
953+
"source": [
954+
"# MATCH\n",
955+
"query_text = text('cs_match_v1(encrypted_utf8_str) @> cs_match_v1(:term)')\n",
956+
"query = select(Example).where(query_text).params(term=CsText(\"example record\", \"examples\", \"encrypted_utf8_str\").to_db_format())\n",
957+
"results = session.execute(query).scalars().all()\n",
958+
"\n",
959+
"for e in results:\n",
960+
" print(f\"MATCH query results: {e}\")"
961+
]
962+
},
963+
{
964+
"cell_type": "markdown",
965+
"id": "c35d9fd3-bfbd-4084-a00d-fee22f7e30d0",
966+
"metadata": {},
967+
"source": [
968+
"### Query by ORE\n",
969+
"\n",
970+
"ORE queries can be peformed too:"
971+
]
972+
},
973+
{
974+
"cell_type": "code",
975+
"execution_count": null,
976+
"id": "5985efb1-1944-41d6-a912-d991095bd7d8",
977+
"metadata": {},
978+
"outputs": [],
979+
"source": [
980+
"# ORE\n",
981+
"cur.execute(\"SELECT * FROM examples WHERE cs_ore_64_8_v1(encrypted_float) > cs_ore_64_8_v1(%s)\", (CsFloat(100.15, \"examples\", \"encrypted_float\").to_db_format(),))\n",
982+
"\n",
983+
"query_text = text('cs_ore_64_8_v1(encrypted_float) > cs_ore_64_8_v1(:term)')\n",
984+
"query = select(Example).where(query_text).params(term=CsFloat(2.0, \"examples\", \"encrypted_float\").to_db_format())\n",
985+
"results = session.execute(query).scalars().all()\n",
986+
"\n",
987+
"for e in results:\n",
988+
" print(f\"MATCH query results: {e}\")"
989+
]
990+
},
880991
{
881992
"cell_type": "markdown",
882993
"id": "e93cf011-66c7-4d93-a3c8-cb6ebe4b34ff",
@@ -925,15 +1036,18 @@
9251036
"metadata": {},
9261037
"outputs": [],
9271038
"source": [
928-
"record_id = results[0].id\n",
1039+
"if len(results) > 0:\n",
1040+
" record_id = results[0].id\n",
9291041
"\n",
930-
"results[0].encrypted_utf8_str = 'example record 1 UPDATED'\n",
931-
"results[0].encrypted_jsonb = json.dumps({'z': {'y': 0}})\n",
932-
"session.commit()\n",
1042+
" results[0].encrypted_utf8_str = 'example record 1 UPDATED'\n",
1043+
" results[0].encrypted_jsonb = json.dumps({'z': {'y': 0}})\n",
1044+
" session.commit()\n",
9331045
"\n",
934-
"updated = session.query(Example).where(Example.id == record_id).first()\n",
1046+
" updated = session.query(Example).where(Example.id == record_id).first()\n",
9351047
"\n",
936-
"print(f\"Updated record: {updated}\")"
1048+
" print(f\"Updated record: {updated}\")\n",
1049+
"else:\n",
1050+
" print(\"Unexpected: results are empty\")"
9371051
]
9381052
},
9391053
{
@@ -963,7 +1077,8 @@
9631077
"\n",
9641078
"That's all for this notebook.\n",
9651079
"\n",
966-
"This notebook showed you how you can interact with CipherStash Encrypt using Python, pyscopg2, and SQLAlchemy."
1080+
"There are many more features not covered in this notebook.\n",
1081+
"Refer to [EQL repository](https://github.com/cipherstash/encrypt-query-language/) and [CipherStash documentation](https://cipherstash.com/docs) for more information."
9671082
]
9681083
}
9691084
],

0 commit comments

Comments
 (0)