From eb7459d872d742fe1eada37b7ec83f237d28c4ae Mon Sep 17 00:00:00 2001 From: Aaron Huizenga Date: Tue, 9 Jun 2020 08:46:56 -0700 Subject: [PATCH 01/14] Created new queries and ran code properly --- Pipfile | 12 +++ Pipfile.lock | 90 +++++++++++++++++++ buddymove_holidayiq.sqlite3 | 0 .../buddymove_holidayiq.py | 14 +++ module1-introduction-to-sql/rpg_queries.py | 44 +++++++++ rpg_db.sqlite3 | 0 6 files changed, 160 insertions(+) create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100644 buddymove_holidayiq.sqlite3 create mode 100644 module1-introduction-to-sql/buddymove_holidayiq.py create mode 100644 module1-introduction-to-sql/rpg_queries.py create mode 100644 rpg_db.sqlite3 diff --git a/Pipfile b/Pipfile new file mode 100644 index 00000000..7130fb71 --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +pandas = "*" + +[requires] +python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 00000000..44573363 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,90 @@ +{ + "_meta": { + "hash": { + "sha256": "fba383031295c98ef4ac605996144102d686f2d38c5a20f33ee0bebae0713200" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "numpy": { + "hashes": [ + "sha256:0172304e7d8d40e9e49553901903dc5f5a49a703363ed756796f5808a06fc233", + "sha256:34e96e9dae65c4839bd80012023aadd6ee2ccb73ce7fdf3074c62f301e63120b", + "sha256:3676abe3d621fc467c4c1469ee11e395c82b2d6b5463a9454e37fe9da07cd0d7", + "sha256:3dd6823d3e04b5f223e3e265b4a1eae15f104f4366edd409e5a5e413a98f911f", + "sha256:4064f53d4cce69e9ac613256dc2162e56f20a4e2d2086b1956dd2fcf77b7fac5", + "sha256:4674f7d27a6c1c52a4d1aa5f0881f1eff840d2206989bae6acb1c7668c02ebfb", + "sha256:7d42ab8cedd175b5ebcb39b5208b25ba104842489ed59fbb29356f671ac93583", + "sha256:965df25449305092b23d5145b9bdaeb0149b6e41a77a7d728b1644b3c99277c1", + "sha256:9c9d6531bc1886454f44aa8f809268bc481295cf9740827254f53c30104f074a", + "sha256:a78e438db8ec26d5d9d0e584b27ef25c7afa5a182d1bf4d05e313d2d6d515271", + "sha256:a7acefddf994af1aeba05bbbafe4ba983a187079f125146dc5859e6d817df824", + "sha256:a87f59508c2b7ceb8631c20630118cc546f1f815e034193dc72390db038a5cb3", + "sha256:ac792b385d81151bae2a5a8adb2b88261ceb4976dbfaaad9ce3a200e036753dc", + "sha256:b03b2c0badeb606d1232e5f78852c102c0a7989d3a534b3129e7856a52f3d161", + "sha256:b39321f1a74d1f9183bf1638a745b4fd6fe80efbb1f6b32b932a588b4bc7695f", + "sha256:cae14a01a159b1ed91a324722d746523ec757357260c6804d11d6147a9e53e3f", + "sha256:cd49930af1d1e49a812d987c2620ee63965b619257bd76eaaa95870ca08837cf", + "sha256:e15b382603c58f24265c9c931c9a45eebf44fe2e6b4eaedbb0d025ab3255228b", + "sha256:e91d31b34fc7c2c8f756b4e902f901f856ae53a93399368d9a0dc7be17ed2ca0", + "sha256:ef627986941b5edd1ed74ba89ca43196ed197f1a206a3f18cc9faf2fb84fd675", + "sha256:f718a7949d1c4f622ff548c572e0c03440b49b9531ff00e4ed5738b459f011e8" + ], + "version": "==1.18.5" + }, + "pandas": { + "hashes": [ + "sha256:034185bb615dc96d08fa13aacba8862949db19d5e7804d6ee242d086f07bcc46", + "sha256:0c9b7f1933e3226cc16129cf2093338d63ace5c85db7c9588e3e1ac5c1937ad5", + "sha256:1f6fcf0404626ca0475715da045a878c7062ed39bc859afc4ccf0ba0a586a0aa", + "sha256:1fc963ba33c299973e92d45466e576d11f28611f3549469aec4a35658ef9f4cc", + "sha256:29b4cfee5df2bc885607b8f016e901e63df7ffc8f00209000471778f46cc6678", + "sha256:2a8b6c28607e3f3c344fe3e9b3cd76d2bf9f59bc8c0f2e582e3728b80e1786dc", + "sha256:2bc2ff52091a6ac481cc75d514f06227dc1b10887df1eb72d535475e7b825e31", + "sha256:415e4d52fcfd68c3d8f1851cef4d947399232741cc994c8f6aa5e6a9f2e4b1d8", + "sha256:519678882fd0587410ece91e3ff7f73ad6ded60f6fcb8aa7bcc85c1dc20ecac6", + "sha256:51e0abe6e9f5096d246232b461649b0aa627f46de8f6344597ca908f2240cbaa", + "sha256:698e26372dba93f3aeb09cd7da2bb6dd6ade248338cfe423792c07116297f8f4", + "sha256:83af85c8e539a7876d23b78433d90f6a0e8aa913e37320785cf3888c946ee874", + "sha256:982cda36d1773076a415ec62766b3c0a21cdbae84525135bdb8f460c489bb5dd", + "sha256:a647e44ba1b3344ebc5991c8aafeb7cca2b930010923657a273b41d86ae225c4", + "sha256:b35d625282baa7b51e82e52622c300a1ca9f786711b2af7cbe64f1e6831f4126", + "sha256:bab51855f8b318ef39c2af2c11095f45a10b74cbab4e3c8199efcc5af314c648" + ], + "index": "pypi", + "version": "==1.0.4" + }, + "python-dateutil": { + "hashes": [ + "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", + "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" + ], + "version": "==2.8.1" + }, + "pytz": { + "hashes": [ + "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", + "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" + ], + "version": "==2020.1" + }, + "six": { + "hashes": [ + "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", + "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" + ], + "version": "==1.15.0" + } + }, + "develop": {} +} diff --git a/buddymove_holidayiq.sqlite3 b/buddymove_holidayiq.sqlite3 new file mode 100644 index 00000000..e69de29b diff --git a/module1-introduction-to-sql/buddymove_holidayiq.py b/module1-introduction-to-sql/buddymove_holidayiq.py new file mode 100644 index 00000000..7c0d393e --- /dev/null +++ b/module1-introduction-to-sql/buddymove_holidayiq.py @@ -0,0 +1,14 @@ +import pandas as pd +import sqlite3 +# df = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/00476/buddymove_holidayiq.csv") + +conn = sqlite3.connect('buddymove_holidayiq.sqlite3') +# df.to_sql("review",con=conn) + +# count how many rows you have + +print(conn.execute("SELECT COUNT(*) FROM review;").fetchall()) + +print(conn.execute("SELECT * FROM review WHERE Nature >= 100 LIMIT 10;").fetchall()) + +print(conn.execute("SELECT AVG(Sports),AVG(Religious),AVG(Nature),AVG(Theatre),AVG(Shopping),AVG(Picnic) FROM review;").fetchall()) \ No newline at end of file diff --git a/module1-introduction-to-sql/rpg_queries.py b/module1-introduction-to-sql/rpg_queries.py new file mode 100644 index 00000000..3f53235a --- /dev/null +++ b/module1-introduction-to-sql/rpg_queries.py @@ -0,0 +1,44 @@ +import sqlite3 +conn = sqlite3.connect('/Users/user/Documents/GitHub/Lambda/DS-Unit-3-Sprint-2-SQL-and-Databases/module1-introduction-to-sql/rpg_db.sqlite3') +c = conn.cursor() + + +#How many total Characters there? +c1 = c +print(c1.execute('SELECT COUNT(*) FROM charactercreator_character;').fetchall()) + +#How many of each specific subclass? + +print(len(c1.execute('SELECT * FROM charactercreator_character;').fetchall()[0][2:])) + +#How many total items? + +print(c1.execute('SELECT COUNT(*) FROM armory_item;').fetchall()) + +#How many of the Items are weapons? + +print(c1.execute('SELECT COUNT(*) FROM armory_weapon;').fetchall()) + +# How many are not? + +print(len(c1.execute('SELECT * FROM armory_item;').fetchall()) - len(c1.execute('SELECT * FROM armory_weapon;').fetchall())) + +# How many Items does each character have? (Return first 20 rows) + +print(c1.execute('SELECT character_id, count(*) FROM charactercreator_character_inventory GROUP BY item_id LIMIT 20;').fetchall()) + +# How many Weapons does each character have? (Return first 20 rows) + +print(c1.execute('SELECT cci.character_id,count(*) FROM armory_weapon as aw, charactercreator_character_inventory as cci WHERE cci.item_id = aw.item_ptr_id GROUP BY cci.character_id LIMIT 20;').fetchall()) + +# On average, how many Items does each Character have? + +table = c1.execute('SELECT character_id, count(*) FROM charactercreator_character_inventory GROUP BY item_id;').fetchall()[:] + +print(sum([x[1] for x in table]) / len(table)) + +# On average, how many Weapons does each character have? + +table = c1.execute('SELECT cci.character_id,count(*) FROM armory_weapon as aw, charactercreator_character_inventory as cci WHERE cci.item_id = aw.item_ptr_id GROUP BY cci.character_id;').fetchall() + +print(sum([x[1] for x in table]) / len(table)) \ No newline at end of file diff --git a/rpg_db.sqlite3 b/rpg_db.sqlite3 new file mode 100644 index 00000000..e69de29b From 8161123289b614f471f561cbd8d15cfd912a6354 Mon Sep 17 00:00:00 2001 From: Aaron Huizenga Date: Tue, 9 Jun 2020 16:45:00 -0700 Subject: [PATCH 02/14] Added insert of titanic and stretch goal practicing with postgreSQL and MongoDB --- .../Stretch_goal_postgres_and_mongo.txt | 19 +++++ module2-sql-for-analysis/elephant_test.py | 83 +++++++++++++++++++ module2-sql-for-analysis/insert_titanic.py | 76 +++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 module2-sql-for-analysis/Stretch_goal_postgres_and_mongo.txt create mode 100644 module2-sql-for-analysis/elephant_test.py create mode 100644 module2-sql-for-analysis/insert_titanic.py diff --git a/module2-sql-for-analysis/Stretch_goal_postgres_and_mongo.txt b/module2-sql-for-analysis/Stretch_goal_postgres_and_mongo.txt new file mode 100644 index 00000000..6104e22e --- /dev/null +++ b/module2-sql-for-analysis/Stretch_goal_postgres_and_mongo.txt @@ -0,0 +1,19 @@ +def increment(x): + return x + 1 + +def double(x): + return x * 2 + +def run_twice(func, arg): + return func(func(arg)) + +def rec_print(n): + print(n) + if n > 0: + rec_print(n-1) + +def add(x,y): + return x + y + +def identity(x): + return x \ No newline at end of file diff --git a/module2-sql-for-analysis/elephant_test.py b/module2-sql-for-analysis/elephant_test.py new file mode 100644 index 00000000..3af8ef4b --- /dev/null +++ b/module2-sql-for-analysis/elephant_test.py @@ -0,0 +1,83 @@ +import sqlite3 +import psycopg2 + +dbname = 'bpecpenu' +user = 'bpecpenu' +password = 'aqJWJbtfkIqQ1oloxEGdC-bEJau3JA4E' +host = 'otto.db.elephantsql.com' + +pg_conn = psycopg2.connect(dbname=dbname, + user=user, + password=password, + host=host) + +pg_curs = pg_conn.cursor() +pg_curs.execute('SELECT * FROM test_table;') +pg_curs.fetchall() + +sl_conn = sqlite3.connect('rpg_db copy.sqlite3') +sl_curs = sl_conn.cursor() +sl_curs.execute('SELECT COUNT(*) FROM charactercreator_character;').fetchall() +sl_curs.execute('SELECT COUNT(DISTINCT name) FROM charactercreator_character;').fetchall() +characters = sl_curs.execute('SELECT * FROM charactercreator_character;').fetchall() +characters[0] +characters[-1] +len(characters) + +sl_curs.execute('PRAGMA table_info(charactercreator_character);').fetchall() + +create_character_table = """ + CREATE TABLE charactercreator_character ( + character_id SERIAL PRIMARY KEY, + name VARCHAR(30), + level INT, + exp INT, + hp INT, + strength INT, + intelligence INT, + dexterity INT, + wisdom INT + ); +""" + +pg_curs.execute(create_character_table) + +show_tables = """ +SELECT * +FROM pg_catalog.pg_tables +WHERE schemaname != 'pg_catalog' +and schemaname != 'information_schema'; +""" + +pg_curs.execute(show_tables) +pg_curs.fetchall() + +example_insert = """ +INSERT INTO charactercreator_character +(name, level, exp, hp, strength, intelligence, dexterity, wisdom) +VALUES """ + str(characters[0][1:]) + ';' + +print(example_insert) + +for character in characters: + insert_chracter = """ + INSERT INTO charactercreator_character + (name, level, exp, hp, strength, intelligence, dexterity, wisdom) + VALUES """ + str(character[1:]) + ';' + # print(insert_chracter)\ + pg_curs.execute(insert_chracter) + +pg_curs.execute('SELECT * FROM charactercreator_character;') +pg_curs.fetchall() + +pg_curs.close() +pg_conn.commit() + +pg_curs = pg_conn.cursor() +pg_characters = pg_curs.execute('SELECT * FROM charactercreator_character;').fetchall() + +characters[0] +pg_characters[0] + +for character, pg_character in zip(characters, pg_characters): + assert characters == pg_character \ No newline at end of file diff --git a/module2-sql-for-analysis/insert_titanic.py b/module2-sql-for-analysis/insert_titanic.py new file mode 100644 index 00000000..d5f999d3 --- /dev/null +++ b/module2-sql-for-analysis/insert_titanic.py @@ -0,0 +1,76 @@ +# import libraries: +import pandas as pd +import psycopg2 +import csv + +# details of postgresql account: +dbname = 'bpecpenu' # same than user +user = 'bpecpenu' # same than dbname +password = 'pm5X5ZXRZjSD9oOEM2t_aLJALLdXNyuN' # Don't commit original pass +host = 'otto.db.elephantsql.com' # from SERVER type + +# stablish connection +pg_conn = psycopg2.connect(dbname=dbname, user=user, password=password, host=host) +pg_conn +# instantiate cursor +pg_curs = pg_conn.cursor() + +# create new empty table and define schema) +create_passengers_table = """ + CREATE TABLE passengers ( + id SERIAL NOT NULL PRIMARY KEY, + survived INT, + pclass INT, + name VARCHAR(200), + sex VARCHAR(20), + age INT, + siblings_spouses INT, + parents_children INT, + fare NUMERIC(30) +); +""" + +pg_curs.execute(create_passengers_table) + +# show table on list of tables +show_tables = """ +SELECT * +FROM pg_catalog.pg_tables +WHERE schemaname != 'pg_catalog' +AND schemaname != 'information_schema'; +""" + +pg_curs.execute(show_tables) +pg_curs.fetchall() + +# read csv file +csv_data = pd.read_csv('titanic.csv') + +# Input each row from the DataFrame into the new table on DataBase +statement = """ + INSERT INTO passengers ( + survived, + pclass, + name, + sex, + age, + siblings_spouses, + parents_children, + fare + ) VALUES + (%s, %s, %s, %s, %s, %s, %s, %s); + """ + +# define data row by row in a for loop where each value is iterated over pandas dataframe using itertuples +data = [row for row in csv_data.itertuples(index=False)] + +# using a for loop to populate the new table passengers +for item in data: + pg_curs.execute( + statement, + item + ) + +# close cursor and commit changes on the DB +pg_curs.close() +pg_conn.commit() \ No newline at end of file From c164a0fccaa5099e25560aeff549da6fcee049a3 Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Wed, 10 Jun 2020 14:47:13 -0700 Subject: [PATCH 03/14] Add files via upload --- .../MongoDB_with_Pymongo_test.ipynb | 1350 +++++++++++++++++ 1 file changed, 1350 insertions(+) create mode 100644 module3-nosql-and-document-oriented-databases/MongoDB_with_Pymongo_test.ipynb diff --git a/module3-nosql-and-document-oriented-databases/MongoDB_with_Pymongo_test.ipynb b/module3-nosql-and-document-oriented-databases/MongoDB_with_Pymongo_test.ipynb new file mode 100644 index 00000000..d18ae26a --- /dev/null +++ b/module3-nosql-and-document-oriented-databases/MongoDB_with_Pymongo_test.ipynb @@ -0,0 +1,1350 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "MongoDB_with_Pymongo_test.ipynb", + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "H1MvisdSz_Ef", + "colab_type": "text" + }, + "source": [ + "# MongoDB with Pymongo\n", + "\n", + "- #### This notebook is to explore/understand MongoDB with Python. Notebooks and REPLs can be great for exploration, but for your assignment you should still turn in .py files.\n", + "\n", + "- #### Some resources:\n", + " - https://docs.atlas.mongodb.com/getting-started/\n", + " - https://api.mongodb.com/python/current/" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6L5Y4mOS0jSs", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "56f80433-f417-4546-ecc8-0ea2d1d42bbb" + }, + "source": [ + "!curl ipecho.net/plain" + ], + "execution_count": 3, + "outputs": [ + { + "output_type": "stream", + "text": [ + "34.83.7.74" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5NjDXR2g1kKb", + "colab_type": "code", + "colab": {} + }, + "source": [ + " mongo_password = 'MpO22RB2O6kgq7ae' # Do not commit this! Reset this if it is exposed" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RCKlIk8Dzy95", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "d9ce0486-c3f2-4018-b3d1-60f09ce25a23" + }, + "source": [ + "!python --version" + ], + "execution_count": 6, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Python 3.6.9\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "mB-C_JoT2hED", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "1f007f11-95d7-4f93-cbd4-c29866469bda" + }, + "source": [ + "!pip install pymongo" + ], + "execution_count": 7, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Requirement already satisfied: pymongo in /usr/local/lib/python3.6/dist-packages (3.10.1)\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ZVD1qMso2_iI", + "colab_type": "code", + "colab": {} + }, + "source": [ + "import pymongo" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "AzFVEC_8zwil", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 363 + }, + "outputId": "7f97f4ca-fead-41c2-b2fb-2638f2403f83" + }, + "source": [ + "# Trying 3.6+ connection string\n", + "client = pymongo.MongoClient(\n", + " \"mongodb+srv://ds15userak:MpO22RB2O6kgq7ae@cluster0-pwwam.mongodb.net/?retryWrites=true&w=majority\")\n", + "db = client.test\n", + "\n", + "# Should work if you install dnspython" + ], + "execution_count": 10, + "outputs": [ + { + "output_type": "error", + "ename": "ConfigurationError", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mConfigurationError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Trying 3.6+ connection string\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m client = pymongo.MongoClient(\n\u001b[0;32m----> 3\u001b[0;31m \"mongodb+srv://ds15userak:MpO22RB2O6kgq7ae@cluster0-pwwam.mongodb.net/?retryWrites=true&w=majority\")\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mdb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mclient\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtest\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pymongo/mongo_client.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, host, port, document_class, tz_aware, connect, type_registry, **kwargs)\u001b[0m\n\u001b[1;32m 619\u001b[0m res = uri_parser.parse_uri(\n\u001b[1;32m 620\u001b[0m \u001b[0mentity\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mport\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalidate\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwarn\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnormalize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 621\u001b[0;31m connect_timeout=timeout)\n\u001b[0m\u001b[1;32m 622\u001b[0m \u001b[0mseeds\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"nodelist\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 623\u001b[0m \u001b[0musername\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"username\"\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0musername\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pymongo/uri_parser.py\u001b[0m in \u001b[0;36mparse_uri\u001b[0;34m(uri, default_port, validate, warn, normalize, connect_timeout)\u001b[0m\n\u001b[1;32m 388\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0muri\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstartswith\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mSRV_SCHEME\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 389\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0m_HAVE_DNSPYTHON\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 390\u001b[0;31m raise ConfigurationError('The \"dnspython\" module must be '\n\u001b[0m\u001b[1;32m 391\u001b[0m 'installed to use mongodb+srv:// URIs')\n\u001b[1;32m 392\u001b[0m \u001b[0mis_srv\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mConfigurationError\u001b[0m: The \"dnspython\" module must be installed to use mongodb+srv:// URIs" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9UvY_DVd3UD-", + "colab_type": "code", + "colab": {} + }, + "source": [ + "# Using 3.4 connection string still, pymongo still having outstanding issues.\n", + "\n", + "\n", + "client = pymongo.MongoClient(\n", + " \"mongodb://ds15userak:MpO22RB2O6kgq7ae@cluster0-shard-00-00-pwwam.mongodb.net:27017,cluster0-shard-00-01-pwwam.mongodb.net:27017,cluster0-shard-00-02-pwwam.mongodb.net:27017/?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true&w=majority\")\n", + "db = client.test" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "RTAXp8uV4GGJ", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 55 + }, + "outputId": "e8850ca2-7747-412b-c872-7d73f9ebca5a" + }, + "source": [ + "db" + ], + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Database(MongoClient(host=['cluster0-shard-00-01-pwwam.mongodb.net:27017', 'cluster0-shard-00-00-pwwam.mongodb.net:27017', 'cluster0-shard-00-02-pwwam.mongodb.net:27017'], document_class=dict, tz_aware=False, connect=True, ssl=True, replicaset='Cluster0-shard-0', authsource='admin', retrywrites=True, w='majority'), 'test')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "NhWA7pF44JtQ", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "outputId": "32cc03ee-87b0-4c6d-f621-6a8b88cd2810" + }, + "source": [ + "dir(db)" + ], + "execution_count": 13, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['_BaseObject__codec_options',\n", + " '_BaseObject__read_concern',\n", + " '_BaseObject__read_preference',\n", + " '_BaseObject__write_concern',\n", + " '_Database__client',\n", + " '_Database__incoming_copying_manipulators',\n", + " '_Database__incoming_manipulators',\n", + " '_Database__name',\n", + " '_Database__outgoing_copying_manipulators',\n", + " '_Database__outgoing_manipulators',\n", + " '__call__',\n", + " '__class__',\n", + " '__delattr__',\n", + " '__dict__',\n", + " '__dir__',\n", + " '__doc__',\n", + " '__eq__',\n", + " '__format__',\n", + " '__ge__',\n", + " '__getattr__',\n", + " '__getattribute__',\n", + " '__getitem__',\n", + " '__gt__',\n", + " '__hash__',\n", + " '__init__',\n", + " '__init_subclass__',\n", + " '__iter__',\n", + " '__le__',\n", + " '__lt__',\n", + " '__module__',\n", + " '__ne__',\n", + " '__new__',\n", + " '__next__',\n", + " '__reduce__',\n", + " '__reduce_ex__',\n", + " '__repr__',\n", + " '__setattr__',\n", + " '__sizeof__',\n", + " '__str__',\n", + " '__subclasshook__',\n", + " '__weakref__',\n", + " '_apply_incoming_copying_manipulators',\n", + " '_apply_incoming_manipulators',\n", + " '_command',\n", + " '_create_or_update_user',\n", + " '_current_op',\n", + " '_default_role',\n", + " '_fix_incoming',\n", + " '_fix_outgoing',\n", + " '_list_collections',\n", + " '_read_preference_for',\n", + " '_retryable_read_command',\n", + " '_write_concern_for',\n", + " 'add_son_manipulator',\n", + " 'add_user',\n", + " 'aggregate',\n", + " 'authenticate',\n", + " 'client',\n", + " 'codec_options',\n", + " 'collection_names',\n", + " 'command',\n", + " 'create_collection',\n", + " 'current_op',\n", + " 'dereference',\n", + " 'drop_collection',\n", + " 'error',\n", + " 'eval',\n", + " 'get_collection',\n", + " 'incoming_copying_manipulators',\n", + " 'incoming_manipulators',\n", + " 'last_status',\n", + " 'list_collection_names',\n", + " 'list_collections',\n", + " 'logout',\n", + " 'name',\n", + " 'next',\n", + " 'outgoing_copying_manipulators',\n", + " 'outgoing_manipulators',\n", + " 'previous_error',\n", + " 'profiling_info',\n", + " 'profiling_level',\n", + " 'read_concern',\n", + " 'read_preference',\n", + " 'remove_user',\n", + " 'reset_error_history',\n", + " 'set_profiling_level',\n", + " 'system_js',\n", + " 'validate_collection',\n", + " 'watch',\n", + " 'with_options',\n", + " 'write_concern']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 13 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "TJMTYl4a502W", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 55 + }, + "outputId": "53e461ea-f864-43f6-de93-308ef866afec" + }, + "source": [ + "db.test" + ], + "execution_count": 14, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "Collection(Database(MongoClient(host=['cluster0-shard-00-01-pwwam.mongodb.net:27017', 'cluster0-shard-00-00-pwwam.mongodb.net:27017', 'cluster0-shard-00-02-pwwam.mongodb.net:27017'], document_class=dict, tz_aware=False, connect=True, ssl=True, replicaset='Cluster0-shard-0', authsource='admin', retrywrites=True, w='majority'), 'test'), 'test')" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 14 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "iuUDzfk-57L0", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 693 + }, + "outputId": "d53b9b4f-3215-46a5-ac74-406203b36822" + }, + "source": [ + "help(db.test.insert_one)" + ], + "execution_count": 15, + "outputs": [ + { + "output_type": "stream", + "text": [ + "Help on method insert_one in module pymongo.collection:\n", + "\n", + "insert_one(document, bypass_document_validation=False, session=None) method of pymongo.collection.Collection instance\n", + " Insert a single document.\n", + " \n", + " >>> db.test.count_documents({'x': 1})\n", + " 0\n", + " >>> result = db.test.insert_one({'x': 1})\n", + " >>> result.inserted_id\n", + " ObjectId('54f112defba522406c9cc208')\n", + " >>> db.test.find_one({'x': 1})\n", + " {u'x': 1, u'_id': ObjectId('54f112defba522406c9cc208')}\n", + " \n", + " :Parameters:\n", + " - `document`: The document to insert. Must be a mutable mapping\n", + " type. If the document does not have an _id field one will be\n", + " added automatically.\n", + " - `bypass_document_validation`: (optional) If ``True``, allows the\n", + " write to opt-out of document level validation. Default is\n", + " ``False``.\n", + " - `session` (optional): a\n", + " :class:`~pymongo.client_session.ClientSession`.\n", + " \n", + " :Returns:\n", + " - An instance of :class:`~pymongo.results.InsertOneResult`.\n", + " \n", + " .. seealso:: :ref:`writes-and-ids`\n", + " \n", + " .. note:: `bypass_document_validation` requires server version\n", + " **>= 3.2**\n", + " \n", + " .. versionchanged:: 3.6\n", + " Added ``session`` parameter.\n", + " \n", + " .. versionchanged:: 3.2\n", + " Added bypass_document_validation support\n", + " \n", + " .. versionadded:: 3.0\n", + "\n" + ], + "name": "stdout" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "s2qGgf4-6KHb", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "4597e4ea-27ff-4995-a8fb-b61bcb16179f" + }, + "source": [ + "db.test.count_documents({'x': 1})" + ], + "execution_count": 16, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "0" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 16 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "-iZlYcNt6QvV", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "3a847566-3822-4caf-e826-047e1ba24537" + }, + "source": [ + "db.test.insert_one({'x': 1})" + ], + "execution_count": 17, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 17 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WWOqUIWA6pqo", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "75da7900-660e-4aaf-8d85-7ecd3c845ac6" + }, + "source": [ + "db.test.count_documents({'x': 1})" + ], + "execution_count": 18, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "1" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 18 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "14kfdz436t4p", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "06e61dba-0c24-41a1-b7a2-ddf2dc839078" + }, + "source": [ + "db.test.insert_one({'x': 1})" + ], + "execution_count": 19, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 19 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vvBBUnDk62-1", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "3feb8751-5d26-4437-d46e-2dea2edba480" + }, + "source": [ + "db.test.count_documents({'x': 1})" + ], + "execution_count": 20, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "2" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 20 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bFqjTJfb640f", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "31ad5847-68c0-4293-cd89-b5690b11abe8" + }, + "source": [ + "db.test.find_one({'x': 1})" + ], + "execution_count": 21, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'_id': ObjectId('5ee142337c01d74871af049a'), 'x': 1}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 21 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "xThIpSte8s6F", + "colab_type": "code", + "colab": {} + }, + "source": [ + "curs = db.test.find({'x': 1})" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-WrEsIpX89jq", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "1c72a201-06e0-4803-f572-c0b8a8d69456" + }, + "source": [ + "curs" + ], + "execution_count": 24, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 24 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "JFMhTPFu9NAR", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "outputId": "51e24508-ff05-4156-c4a6-ea9ecf7e7707" + }, + "source": [ + "dir(curs)" + ], + "execution_count": 26, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "['_Cursor__address',\n", + " '_Cursor__batch_size',\n", + " '_Cursor__check_okay_to_chain',\n", + " '_Cursor__codec_options',\n", + " '_Cursor__collation',\n", + " '_Cursor__collection',\n", + " '_Cursor__comment',\n", + " '_Cursor__data',\n", + " '_Cursor__die',\n", + " '_Cursor__empty',\n", + " '_Cursor__exhaust',\n", + " '_Cursor__exhaust_mgr',\n", + " '_Cursor__explain',\n", + " '_Cursor__explicit_session',\n", + " '_Cursor__hint',\n", + " '_Cursor__id',\n", + " '_Cursor__killed',\n", + " '_Cursor__limit',\n", + " '_Cursor__manipulate',\n", + " '_Cursor__max',\n", + " '_Cursor__max_await_time_ms',\n", + " '_Cursor__max_scan',\n", + " '_Cursor__max_time_ms',\n", + " '_Cursor__min',\n", + " '_Cursor__modifiers',\n", + " '_Cursor__ordering',\n", + " '_Cursor__projection',\n", + " '_Cursor__query_flags',\n", + " '_Cursor__query_spec',\n", + " '_Cursor__read_concern',\n", + " '_Cursor__read_preference',\n", + " '_Cursor__retrieved',\n", + " '_Cursor__return_key',\n", + " '_Cursor__send_message',\n", + " '_Cursor__session',\n", + " '_Cursor__set_hint',\n", + " '_Cursor__show_record_id',\n", + " '_Cursor__skip',\n", + " '_Cursor__snapshot',\n", + " '_Cursor__spec',\n", + " '__class__',\n", + " '__copy__',\n", + " '__deepcopy__',\n", + " '__del__',\n", + " '__delattr__',\n", + " '__dict__',\n", + " '__dir__',\n", + " '__doc__',\n", + " '__enter__',\n", + " '__eq__',\n", + " '__exit__',\n", + " '__format__',\n", + " '__ge__',\n", + " '__getattribute__',\n", + " '__getitem__',\n", + " '__gt__',\n", + " '__hash__',\n", + " '__init__',\n", + " '__init_subclass__',\n", + " '__iter__',\n", + " '__le__',\n", + " '__lt__',\n", + " '__module__',\n", + " '__ne__',\n", + " '__new__',\n", + " '__next__',\n", + " '__reduce__',\n", + " '__reduce_ex__',\n", + " '__repr__',\n", + " '__setattr__',\n", + " '__sizeof__',\n", + " '__str__',\n", + " '__subclasshook__',\n", + " '__weakref__',\n", + " '_clone',\n", + " '_clone_base',\n", + " '_deepcopy',\n", + " '_getmore_class',\n", + " '_query_class',\n", + " '_read_preference',\n", + " '_refresh',\n", + " '_unpack_response',\n", + " 'add_option',\n", + " 'address',\n", + " 'alive',\n", + " 'batch_size',\n", + " 'clone',\n", + " 'close',\n", + " 'collation',\n", + " 'collection',\n", + " 'comment',\n", + " 'count',\n", + " 'cursor_id',\n", + " 'distinct',\n", + " 'explain',\n", + " 'hint',\n", + " 'limit',\n", + " 'max',\n", + " 'max_await_time_ms',\n", + " 'max_scan',\n", + " 'max_time_ms',\n", + " 'min',\n", + " 'next',\n", + " 'remove_option',\n", + " 'retrieved',\n", + " 'rewind',\n", + " 'session',\n", + " 'skip',\n", + " 'sort',\n", + " 'where']" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 26 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "SZtKBznd9OfH", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 52 + }, + "outputId": "b5ab7937-f88f-46be-d371-d3bac781e94f" + }, + "source": [ + "list(curs)" + ], + "execution_count": 27, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[{'_id': ObjectId('5ee142337c01d74871af049a'), 'x': 1},\n", + " {'_id': ObjectId('5ee1426a7c01d74871af049b'), 'x': 1}]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 27 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "zZd_fcd19YB4", + "colab_type": "code", + "colab": {} + }, + "source": [ + "aarons_doc ={\n", + " 'name': 'aaron',\n", + " 'favorite_animal': 'dog',\n", + " 'favorite_color': 'green',\n", + " 'favorite_number': 5,\n", + " 'favorite_tv_show': 'riverdale'\n", + "}\n", + "\n", + "juds_doc = {\n", + " 'name': 'jud',\n", + " 'favorite_animal': 'liger',\n", + " 'favorite_color': 'green',\n", + " 'favorite_sport': 'football'\n", + "}\n", + "\n", + "baisali_doc = {\n", + " 'name': 'baisali',\n", + " 'favorite_animal': 'elephant',\n", + " 'favorite_color': 'red',\n", + " 'favorite_number': 2\n", + "}\n", + "\n", + "faraazs_doc ={\n", + " 'name': 'faraaz',\n", + " 'favorite_animal': 'ring-tailed lemur',\n", + " 'favorite_color': 'forest green',\n", + " 'favorite_restaurant': 'in-n-out'\n", + "}\n", + "\n", + "all_docs = [aarons_doc, juds_doc, baisali_doc, faraazs_doc]" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "-0jPPNqL_cAz", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "9ed94755-e9a3-4314-d70c-15ef9f1e6468" + }, + "source": [ + "len(all_docs)" + ], + "execution_count": 48, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "4" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 48 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fLLW7UFt_5UH", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "004e080c-6360-4384-a5f7-a6257975a99d" + }, + "source": [ + "db.test.insert_many(all_docs)" + ], + "execution_count": 49, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 49 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "FyPE1SXSAAw0", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 711 + }, + "outputId": "bc20bc61-8f20-418c-f90f-e216607f7e2d" + }, + "source": [ + "list(db.test.find())" + ], + "execution_count": 50, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[{'_id': ObjectId('5ee142337c01d74871af049a'), 'x': 1},\n", + " {'_id': ObjectId('5ee1426a7c01d74871af049b'), 'x': 1},\n", + " {'_id': ObjectId('5ee149217c01d74871af049c'),\n", + " 'favorite_animal': 'dog',\n", + " 'favorite_color': 'green',\n", + " 'favorite_number': 5,\n", + " 'favorite_tv_show': 'riverdale'},\n", + " {'_id': ObjectId('5ee149217c01d74871af049d'),\n", + " 'favorite_animal': 'liger',\n", + " 'favorite_color': 'green',\n", + " 'favorite_sport': 'football'},\n", + " {'_id': ObjectId('5ee149217c01d74871af049e'),\n", + " 'favorite_animal': 'elephant',\n", + " 'favorite_color': 'red',\n", + " 'favorite_number': 2},\n", + " {'_id': ObjectId('5ee149217c01d74871af049f'),\n", + " 'favorite_animal': 'ring-tailed lemur',\n", + " 'favorite_color': 'forest green',\n", + " 'favorite_restaurant': 'in-n-out'},\n", + " {'_id': ObjectId('5ee149bf7c01d74871af04a0'),\n", + " 'favorite_animal': 'dog',\n", + " 'favorite_color': 'green',\n", + " 'favorite_number': 5,\n", + " 'favorite_tv_show': 'riverdale',\n", + " 'name': 'aaron'},\n", + " {'_id': ObjectId('5ee149bf7c01d74871af04a1'),\n", + " 'favorite_animal': 'liger',\n", + " 'favorite_color': 'green',\n", + " 'favorite_sport': 'football',\n", + " 'name': 'jud'},\n", + " {'_id': ObjectId('5ee149bf7c01d74871af04a2'),\n", + " 'favorite_animal': 'elephant',\n", + " 'favorite_color': 'red',\n", + " 'favorite_number': 2,\n", + " 'name': 'baisali'},\n", + " {'_id': ObjectId('5ee149bf7c01d74871af04a3'),\n", + " 'favorite_animal': 'ring-tailed lemur',\n", + " 'favorite_color': 'forest green',\n", + " 'favorite_restaurant': 'in-n-out',\n", + " 'name': 'faraaz'}]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 50 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "W3LVccB6AHGc", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 191 + }, + "outputId": "caf00c95-543a-401d-e7c6-a764a4f540d9" + }, + "source": [ + "more_docs = []\n", + "for i in range(10):\n", + " doc = {'even': i % 2 == 0}\n", + " doc['value'] = i\n", + " more_docs.append(doc)\n", + "\n", + "more_docs" + ], + "execution_count": 51, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[{'even': True, 'value': 0},\n", + " {'even': False, 'value': 1},\n", + " {'even': True, 'value': 2},\n", + " {'even': False, 'value': 3},\n", + " {'even': True, 'value': 4},\n", + " {'even': False, 'value': 5},\n", + " {'even': True, 'value': 6},\n", + " {'even': False, 'value': 7},\n", + " {'even': True, 'value': 8},\n", + " {'even': False, 'value': 9}]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 51 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "r5IyJ8ZxCuFX", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "702d16cd-d84c-4840-e6db-30f950080990" + }, + "source": [ + "db.test.insert_many(more_docs)" + ], + "execution_count": 52, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 52 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "wy4R_X8bCyyk", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "0b04ce7a-f4cc-47c8-9c38-94c6267ddd38" + }, + "source": [ + "list(db.test.find({'even': True, 'value': 0}))" + ], + "execution_count": 53, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[{'_id': ObjectId('5ee14a8a7c01d74871af04a4'), 'even': True, 'value': 0}]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 53 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LIKwMwMBDBDh", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 104 + }, + "outputId": "0bc0f7f4-3758-453c-b61a-0633c6bbec10" + }, + "source": [ + "list(db.test.find({'even': True}))" + ], + "execution_count": 54, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[{'_id': ObjectId('5ee14a8a7c01d74871af04a4'), 'even': True, 'value': 0},\n", + " {'_id': ObjectId('5ee14a8a7c01d74871af04a6'), 'even': True, 'value': 2},\n", + " {'_id': ObjectId('5ee14a8a7c01d74871af04a8'), 'even': True, 'value': 4},\n", + " {'_id': ObjectId('5ee14a8a7c01d74871af04aa'), 'even': True, 'value': 6},\n", + " {'_id': ObjectId('5ee14a8a7c01d74871af04ac'), 'even': True, 'value': 8}]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 54 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rkc25vuNDl65", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 364 + }, + "outputId": "839f8824-a75e-4459-ad2b-e495491b97f8" + }, + "source": [ + "list(db.test.find({'favorite_color': 'green'}))" + ], + "execution_count": 57, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[{'_id': ObjectId('5ee149217c01d74871af049c'),\n", + " 'favorite_animal': 'dog',\n", + " 'favorite_color': 'green',\n", + " 'favorite_number': 5,\n", + " 'favorite_tv_show': 'riverdale'},\n", + " {'_id': ObjectId('5ee149217c01d74871af049d'),\n", + " 'favorite_animal': 'liger',\n", + " 'favorite_color': 'green',\n", + " 'favorite_sport': 'football'},\n", + " {'_id': ObjectId('5ee149bf7c01d74871af04a0'),\n", + " 'favorite_animal': 'dog',\n", + " 'favorite_color': 'green',\n", + " 'favorite_number': 5,\n", + " 'favorite_tv_show': 'riverdale',\n", + " 'name': 'aaron'},\n", + " {'_id': ObjectId('5ee149bf7c01d74871af04a1'),\n", + " 'favorite_animal': 'liger',\n", + " 'favorite_color': 'green',\n", + " 'favorite_sport': 'football',\n", + " 'name': 'jud'}]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 57 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "11yhBh4yD4I_", + "colab_type": "code", + "colab": {} + }, + "source": [ + "# What is CRUD?\n", + "# C - Create\n", + "# R - Read\n", + "# U - Update\n", + "# D - Delete\n", + "\n", + "# AKA - As Aaron Gallant puts it - most apps" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "R8CtxQGFEURL", + "colab_type": "code", + "colab": {} + }, + "source": [ + "rpg_character = (1, \"King Bob\", 10, 3, 0, 0, 0)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "o5izPX5TFAPt", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "f5c5a87d-bba1-43d9-d9cd-e0b40c892d3d" + }, + "source": [ + "# Lazy and not good for long term goals\n", + "\n", + "db.test.insert_one({'rpg_character': rpg_character})" + ], + "execution_count": 62, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 62 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "aXKGzyLvFb47", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 52 + }, + "outputId": "d18b2475-6d51-4a48-a953-c937d9e4525c" + }, + "source": [ + "db.test.find_one({'rpg_character': rpg_character})" + ], + "execution_count": 63, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'_id': ObjectId('5ee14d3e7c01d74871af04ae'),\n", + " 'rpg_character': [1, 'King Bob', 10, 3, 0, 0, 0]}" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 63 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fUtgXELHFjAt", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 35 + }, + "outputId": "982d8f63-8e04-46bf-bb5b-6b69369747bc" + }, + "source": [ + "# Ideal even though SCHEMA isn't required, we should make informative/useful\n", + "# key names in our docs\n", + "\n", + "rpg_doc = {\n", + " 'sql_key': rpg_character[0],\n", + " 'name': rpg_character[1],\n", + " 'hp': rpg_character[2],\n", + " 'level': rpg_character[3]\n", + "}\n", + "db.test.insert_one(rpg_doc)" + ], + "execution_count": 65, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 65 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IFuPHd5fGRsM", + "colab_type": "code", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 104 + }, + "outputId": "0e29382f-6ca6-4c24-8b41-f42de72402ea" + }, + "source": [ + "list(db.test.find(rpg_doc))" + ], + "execution_count": 66, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[{'_id': ObjectId('5ee14e647c01d74871af04af'),\n", + " 'hp': 10,\n", + " 'level': 3,\n", + " 'name': 'King Bob',\n", + " 'sql_key': 1}]" + ] + }, + "metadata": { + "tags": [] + }, + "execution_count": 66 + } + ] + } + ] +} \ No newline at end of file From a60bb2bef0c0e4650abff373212aff650cfa2cd1 Mon Sep 17 00:00:00 2001 From: Aaron Huizenga Date: Wed, 10 Jun 2020 16:35:40 -0700 Subject: [PATCH 04/14] RPG_mongoDB test and .py updates --- .../RPG_mongoDB.py | 40 ++++ .../mongoDB.py | 187 ++++++++++++++++++ .../mongodb_test.py | 111 +++++++++++ 3 files changed, 338 insertions(+) create mode 100644 module3-nosql-and-document-oriented-databases/RPG_mongoDB.py create mode 100644 module3-nosql-and-document-oriented-databases/mongoDB.py create mode 100644 module3-nosql-and-document-oriented-databases/mongodb_test.py diff --git a/module3-nosql-and-document-oriented-databases/RPG_mongoDB.py b/module3-nosql-and-document-oriented-databases/RPG_mongoDB.py new file mode 100644 index 00000000..60ba9186 --- /dev/null +++ b/module3-nosql-and-document-oriented-databases/RPG_mongoDB.py @@ -0,0 +1,40 @@ +""" MongoDB """ + +import pymongo +import sqlite3 + +client = pymongo.MongoClient( + "mongodb+srv://ds15userak:MpO22RB2O6kgq7ae@cluster0-pwwam.mongodb.net/?retryWrites=true&w=majority") +db = client.test + +client.nodes + +sl_conn = sqlite3.connect('rpg_db.sqlite3') +sl_curs = sl_conn.cursor() + +query1 = 'SELECT * FROM charactercreator_character;' +characters = sl_curs.execute(query1).fetchall() + +# my dictionary for charactercreator_character table +docs = [] +for character in characters: + doc1 = {'table1' : 'charactercreator_character'} + doc1['character_id'] = character[0] + doc1['name'] = character[1] + doc1['level'] = character[2] + doc1['exp'] = character[3] + doc1['hp'] = character[4] + doc1['strength'] = character[5] + doc1['intelligence'] = character[6] + doc1['dexterity'] = character[7] + doc1['wisdom'] = character[8] + docs.append(doc1) + +# transfer data to mongoDB +db.test.insert_many(docs) + +# Confirm that table was added in mongoDB +print(db.test.find_one()) + +query2 = 'SELECT * FROM armory_item;' +items = sl_curs.execute(query2).fetchall() \ No newline at end of file diff --git a/module3-nosql-and-document-oriented-databases/mongoDB.py b/module3-nosql-and-document-oriented-databases/mongoDB.py new file mode 100644 index 00000000..b7c3306e --- /dev/null +++ b/module3-nosql-and-document-oriented-databases/mongoDB.py @@ -0,0 +1,187 @@ +import pymongo +import sqlite3 + +client = pymongo.MongoClient( + "mongodb+srv://ds15userak:MpO22RB2O6kgq7ae@cluster0-pwwam.mongodb.net/?retryWrites=true&w=majority") +db = client.test + +client.nodes + +sl_conn = sqlite3.connect('rpg_db.sqlite3') +sl_curs = sl_conn.cursor() + +query1 = 'SELECT * FROM charactercreator_character;' +characters = sl_curs.execute(query1).fetchall() + +# This wil be my dictionary for the charactercreator_character table +charactercreator_character = {} +for character in characters: + cc = { + 'character_id' : character[0], + 'name' : character[1], + 'level' : character[2], + 'exp' : character[3], + 'hp' : character[4], + 'strength' : character[5], + 'intelligence' : character[6], + 'dexterity' : character[7], + 'wisdom' : character[8] + } + charactercreator_character.update({str(character[0]): cc}) + +# This will transfer the data to mongoDB +db.test.insert_one(charactercreator_character) + +# This will confirm that the table was added in mongoDB +print(db.test.find_one()) + +query2 = 'SELECT * FROM armory_item;' +items = sl_curs.execute(query2).fetchall() + +# my dictionary for armory_item table +armory_item = {} +for item in items: + ai = { + 'item_id': item[0], + 'name' : item[1], + 'value' : item[2], + 'weight' : item[3] +} + armory_item.update({str(item[0]): ai}) + +# transfer data to mongoDB +db.test.insert_one(armory_item) + +# Confirm that table was added in mongoDB +print(db.test.find(armory_item)) + +query3 = 'SELECT * FROM armory_weapon;' +weapons = sl_curs.execute(query3).fetchall() + +# my dictionary for armory_weapon table +armory_weapon = {} +for weapon in weapons: + aw = { + 'item__ptr_id': item[0], + 'power' : item[1] +} + armory_weapon.update({str(weapon[0]): aw}) + +# transfer data to mongoDB +db.test.insert_one(armory_weapon) + +# Confirm that table was added in mongoDB +print(db.test.find(armory_weapon)) + +query4 = 'SELECT * FROM charactercreator_character_inventory;' +stocks = sl_curs.execute(query4).fetchall() + +# my dictionary for charactercreator_character_inventory table +charactercreator_character_inventory = {} +for stock in stocks: + cci = { + 'id': stock[0], + 'character_id' : stock[1], + 'item_id' : stock[2] +} + charactercreator_character_inventory.update({str(stock[0]): cci}) + +# transfer data to mongoDB +db.test.insert_one(charactercreator_character_inventory) + +# Confirm that table was added in mongoDB +print(db.test.find(charactercreator_character_inventory)) + +query5 = 'SELECT * FROM charactercreator_mage;' +mages = sl_curs.execute(query5).fetchall() + +# my dictionary for charactercreator_mage table +charactercreator_mage = {} +for mage in mages: + ccm = { + 'character_ptr_id': mage[0], + 'has_pet' : mage[1], + 'mana' : mage[2] +} + charactercreator_mage.update({str(mage[0]): ccm}) + +# transfer data to mongoDB +db.test.insert_one(charactercreator_mage) + +# Confirm that table was added in mongoDB +print(db.test.find(charactercreator_mage)) + +query6 = 'SELECT * FROM charactercreator_thief;' +thieves = sl_curs.execute(query6).fetchall() + +# my dictionary for charactercreator_thief table +charactercreator_thief = {} +for thief in thieves: + cct = { + 'character_ptr_id': thief[0], + 'is_sneaking' : thief[1], + 'energy' : thief[2] +} + charactercreator_thief.update({str(thief[0]): cct}) + +# transfer data to mongoDB +db.test.insert_one(charactercreator_thief) + +# Confirm that table was added in mongoDB +print(db.test.find(charactercreator_thief)) + +query7 = 'SELECT * FROM charactercreator_cleric;' +clerics = sl_curs.execute(query7).fetchall() + +# my dictionary for charactercreator_cleric table +charactercreator_cleric = {} +for cleric in clerics: + ccc = { + 'character_ptr_id': cleric[0], + 'using_shield' : cleric[1], + 'mana' : cleric[2] +} + charactercreator_cleric.update({str(cleric[0]): ccc}) + +# transfer data to mongoDB +db.test.insert_one(charactercreator_cleric) + +# Confirm that table was added in mongoDB +print(db.test.find(charactercreator_cleric)) + +query8 = 'SELECT * FROM charactercreator_fighter;' +fighters = sl_curs.execute(query8).fetchall() + +# my dictionary for charactercreator_cleric table +charactercreator_fighter = {} +for fighter in fighters: + ccf = { + 'character_ptr_id': fighter[0], + 'using_shield' : fighter[1], + 'rage' : fighter[2] +} + charactercreator_fighter.update({str(fighter[0]): ccf}) + +# transfer data to mongoDB +db.test.insert_one(charactercreator_fighter) + +# Confirm that table was added in mongoDB +print(db.test.find(charactercreator_fighter)) + +query9 = 'SELECT * FROM charactercreator_necromancer;' +nmcs = sl_curs.execute(query9).fetchall() + +# my dictionary for charactercreator_necromancer table +charactercreator_necromancer = {} +for nmc in nmcs: + ccn = { + 'mage_ptr_id': nmc[0], + 'talisman_charged' : nmc[1] +} + charactercreator_necromancer.update({str(nmc[0]): ccn}) + +# transfer data to mongoDB +db.test.insert_one(charactercreator_necromancer) + +# Confirm that table was added in mongoDB +print(db.test.find(charactercreator_necromancer)) \ No newline at end of file diff --git a/module3-nosql-and-document-oriented-databases/mongodb_test.py b/module3-nosql-and-document-oriented-databases/mongodb_test.py new file mode 100644 index 00000000..bbe91338 --- /dev/null +++ b/module3-nosql-and-document-oriented-databases/mongodb_test.py @@ -0,0 +1,111 @@ +import pymongo +client = pymongo.MongoClient( + "mongodb://aaron-huizenga@lambdastudents.com:MpO22RB2O6kgq7ae@mycluster0-shard-00-00.mongodb.net:27017,mycluster0-shard-00-01.mongodb.net:27017,mycluster0-shard-00-02.mongodb.net:27017/admin?ssl=true&replicaSet=Mycluster0-shard-0&authSource=admin") +db = client.test + +db + +dir(db) + +db.test + +help(db.test.insert_one) + +db.test.count_documents({'x': 1}) + +db.insert_one({'x': 1}) + +db.test.count_documents({'x': 1}) + +db.insert_one({'x': 1}) + +db.test.count_documents({'x': 1}) + +db.test.find_one({'x': 1}) + +curs = db.test.find({'x': 1}) + +curs + +dir(curs) + +list(curs) + +aarons_doc ={ + 'name': 'aaron', + 'favorite_animal': 'dog', + 'favorite_color': 'green', + 'favorite_number': 5, + 'favorite_tv_show': 'riverdale' +} + +juds_doc = { + 'name': 'jud', + 'favorite_animal': 'liger', + 'favorite_color': 'green', + 'favorite_sport': 'football' +} + +baisali_doc = { + 'name': 'baisali', + 'favorite_animal': 'elephant', + 'favorite_color': 'red', + 'favorite_number': 2 +} + +faraazs_doc ={ + 'name': 'faraaz', + 'favorite_animal': 'ring-tailed lemur', + 'favorite_color': 'forest green', + 'favorite_restaurant': 'in-n-out' +} + +all_docs = [aarons_doc, juds_doc, baisali_doc, faraazs_doc] + +len(all_docs) + +db.test.insert_many(all_docs) + +list(db.test.find()) + +more_docs = [] +for i in range(10): + doc = {'even': i % 2 == 0} + doc['value'] = i + more_docs.append(doc) + +more_docs + +db.test.insert_many(more_docs) + +list(db.test.find({'even': True, 'value': 0})) + +list(db.test.find({'even': True})) + +list(db.test.find({'favorite_color': 'green'})) + +# What is CRUD? +# C - Create +# R - Read +# U - Update +# D - Delete + +# AKA - As Aaron Gallant puts it - most apps +rpg_character = (1, "King Bob", 10, 3, 0, 0, 0) + +# Lazy and not good for long term goals +db.test.insert_one({'rpg_character': rpg_character}) + +db.test.find_one({'rpg_character': rpg_character}) + +# Ideal even though SCHEMA isn't required, we should make informative/useful +# key names in our docs +rpg_doc = { + 'sql_key': rpg_character[0], + 'name': rpg_character[1], + 'hp': rpg_character[2], + 'level': rpg_character[3] +} +db.test.insert_one(rpg_doc) + +list(db.test.find(rpg_doc)) \ No newline at end of file From dbc09e22a2870a5e5419a1336dd02acfb0acce3f Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Thu, 11 Jun 2020 13:52:34 -0700 Subject: [PATCH 05/14] Add files via upload --- .../titanic1.csv | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 module4-acid-and-database-scalability-tradeoffs/titanic1.csv diff --git a/module4-acid-and-database-scalability-tradeoffs/titanic1.csv b/module4-acid-and-database-scalability-tradeoffs/titanic1.csv new file mode 100644 index 00000000..a140d63c --- /dev/null +++ b/module4-acid-and-database-scalability-tradeoffs/titanic1.csv @@ -0,0 +1,157 @@ +PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked +1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S +2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C +3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S +4,1,1,"Futrelle, Mrs. Jacques Heath (Lily May Peel)",female,35,1,0,113803,53.1,C123,S +5,0,3,"Allen, Mr. William Henry",male,35,0,0,373450,8.05,,S +6,0,3,"Moran, Mr. James",male,,0,0,330877,8.4583,,Q +7,0,1,"McCarthy, Mr. Timothy J",male,54,0,0,17463,51.8625,E46,S +8,0,3,"Palsson, Master. Gosta Leonard",male,2,3,1,349909,21.075,,S +9,1,3,"Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)",female,27,0,2,347742,11.1333,,S +10,1,2,"Nasser, Mrs. Nicholas (Adele Achem)",female,14,1,0,237736,30.0708,,C +11,1,3,"Sandstrom, Miss. Marguerite Rut",female,4,1,1,PP 9549,16.7,G6,S +12,1,1,"Bonnell, Miss. Elizabeth",female,58,0,0,113783,26.55,C103,S +13,0,3,"Saundercock, Mr. William Henry",male,20,0,0,A/5. 2151,8.05,,S +14,0,3,"Andersson, Mr. Anders Johan",male,39,1,5,347082,31.275,,S +15,0,3,"Vestrom, Miss. Hulda Amanda Adolfina",female,14,0,0,350406,7.8542,,S +16,1,2,"Hewlett, Mrs. (Mary D Kingcome) ",female,55,0,0,248706,16,,S +17,0,3,"Rice, Master. Eugene",male,2,4,1,382652,29.125,,Q +18,1,2,"Williams, Mr. Charles Eugene",male,,0,0,244373,13,,S +19,0,3,"Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele)",female,31,1,0,345763,18,,S +20,1,3,"Masselmani, Mrs. Fatima",female,,0,0,2649,7.225,,C +21,0,2,"Fynney, Mr. Joseph J",male,35,0,0,239865,26,,S +22,1,2,"Beesley, Mr. Lawrence",male,34,0,0,248698,13,D56,S +23,1,3,"McGowan, Miss. Anna 'Annie'",female,15,0,0,330923,8.0292,,Q +24,1,1,"Sloper, Mr. William Thompson",male,28,0,0,113788,35.5,A6,S +25,0,3,"Palsson, Miss. Torborg Danira",female,8,3,1,349909,21.075,,S +26,1,3,"Asplund, Mrs. Carl Oscar (Selma Augusta Emilia Johansson)",female,38,1,5,347077,31.3875,,S +27,0,3,"Emir, Mr. Farred Chehab",male,,0,0,2631,7.225,,C +28,0,1,"Fortune, Mr. Charles Alexander",male,19,3,2,19950,263,C23 C25 C27,S +29,1,3,"O'Dwyer, Miss. Ellen 'Nellie'",female,,0,0,330959,7.8792,,Q +30,0,3,"Todoroff, Mr. Lalio",male,,0,0,349216,7.8958,,S +31,0,1,"Uruchurtu, Don. Manuel E",male,40,0,0,PC 17601,27.7208,,C +32,1,1,"Spencer, Mrs. William Augustus (Marie Eugenie)",female,,1,0,PC 17569,146.5208,B78,C +33,1,3,"Glynn, Miss. Mary Agatha",female,,0,0,335677,7.75,,Q +34,0,2,"Wheadon, Mr. Edward H",male,66,0,0,C.A. 24579,10.5,,S +35,0,1,"Meyer, Mr. Edgar Joseph",male,28,1,0,PC 17604,82.1708,,C +36,0,1,"Holverson, Mr. Alexander Oskar",male,42,1,0,113789,52,,S +37,1,3,"Mamee, Mr. Hanna",male,,0,0,2677,7.2292,,C +38,0,3,"Cann, Mr. Ernest Charles",male,21,0,0,A./5. 2152,8.05,,S +39,0,3,"Vander Planke, Miss. Augusta Maria",female,18,2,0,345764,18,,S +40,1,3,"Nicola-Yarred, Miss. Jamila",female,14,1,0,2651,11.2417,,C +41,0,3,"Ahlin, Mrs. Johan (Johanna Persdotter Larsson)",female,40,1,0,7546,9.475,,S +42,0,2,"Turpin, Mrs. William John Robert (Dorothy Ann Wonnacott)",female,27,1,0,11668,21,,S +43,0,3,"Kraeff, Mr. Theodor",male,,0,0,349253,7.8958,,C +44,1,2,"Laroche, Miss. Simonne Marie Anne Andree",female,3,1,2,SC/Paris 2123,41.5792,,C +45,1,3,"Devaney, Miss. Margaret Delia",female,19,0,0,330958,7.8792,,Q +46,0,3,"Rogers, Mr. William John",male,,0,0,S.C./A.4. 23567,8.05,,S +47,0,3,"Lennon, Mr. Denis",male,,1,0,370371,15.5,,Q +48,1,3,"O'Driscoll, Miss. Bridget",female,,0,0,14311,7.75,,Q +49,0,3,"Samaan, Mr. Youssef",male,,2,0,2662,21.6792,,C +50,0,3,"Arnold-Franchi, Mrs. Josef (Josefine Franchi)",female,18,1,0,349237,17.8,,S +51,0,3,"Panula, Master. Juha Niilo",male,7,4,1,3101295,39.6875,,S +52,0,3,"Nosworthy, Mr. Richard Cater",male,21,0,0,A/4. 39886,7.8,,S +53,1,1,"Harper, Mrs. Henry Sleeper (Myna Haxtun)",female,49,1,0,PC 17572,76.7292,D33,C +54,1,2,"Faunthorpe, Mrs. Lizzie (Elizabeth Anne Wilkinson)",female,29,1,0,2926,26,,S +55,0,1,"Ostby, Mr. Engelhart Cornelius",male,65,0,1,113509,61.9792,B30,C +56,1,1,"Woolner, Mr. Hugh",male,,0,0,19947,35.5,C52,S +57,1,2,"Rugg, Miss. Emily",female,21,0,0,C.A. 31026,10.5,,S +58,0,3,"Novel, Mr. Mansouer",male,28.5,0,0,2697,7.2292,,C +59,1,2,"West, Miss. Constance Mirium",female,5,1,2,C.A. 34651,27.75,,S +60,0,3,"Goodwin, Master. William Frederick",male,11,5,2,CA 2144,46.9,,S +61,0,3,"Sirayanian, Mr. Orsen",male,22,0,0,2669,7.2292,,C +62,1,1,"Icard, Miss. Amelie",female,38,0,0,113572,80,B28, +63,0,1,"Harris, Mr. Henry Birkhardt",male,45,1,0,36973,83.475,C83,S +64,0,3,"Skoog, Master. Harald",male,4,3,2,347088,27.9,,S +65,0,1,"Stewart, Mr. Albert A",male,,0,0,PC 17605,27.7208,,C +66,1,3,"Moubarek, Master. Gerios",male,,1,1,2661,15.2458,,C +67,1,2,"Nye, Mrs. (Elizabeth Ramell)",female,29,0,0,C.A. 29395,10.5,F33,S +68,0,3,"Crease, Mr. Ernest James",male,19,0,0,S.P. 3464,8.1583,,S +69,1,3,"Andersson, Miss. Erna Alexandra",female,17,4,2,3101281,7.925,,S +70,0,3,"Kink, Mr. Vincenz",male,26,2,0,315151,8.6625,,S +71,0,2,"Jenkin, Mr. Stephen Curnow",male,32,0,0,C.A. 33111,10.5,,S +72,0,3,"Goodwin, Miss. Lillian Amy",female,16,5,2,CA 2144,46.9,,S +73,0,2,"Hood, Mr. Ambrose Jr",male,21,0,0,S.O.C. 14879,73.5,,S +74,0,3,"Chronopoulos, Mr. Apostolos",male,26,1,0,2680,14.4542,,C +75,1,3,"Bing, Mr. Lee",male,32,0,0,1601,56.4958,,S +76,0,3,"Moen, Mr. Sigurd Hansen",male,25,0,0,348123,7.65,F G73,S +77,0,3,"Staneff, Mr. Ivan",male,,0,0,349208,7.8958,,S +78,0,3,"Moutal, Mr. Rahamin Haim",male,,0,0,374746,8.05,,S +79,1,2,"Caldwell, Master. Alden Gates",male,0.83,0,2,248738,29,,S +80,1,3,"Dowdell, Miss. Elizabeth",female,30,0,0,364516,12.475,,S +81,0,3,"Waelens, Mr. Achille",male,22,0,0,345767,9,,S +82,1,3,"Sheerlinck, Mr. Jan Baptist",male,29,0,0,345779,9.5,,S +83,1,3,"McDermott, Miss. Brigdet Delia",female,,0,0,330932,7.7875,,Q +84,0,1,"Carrau, Mr. Francisco M",male,28,0,0,113059,47.1,,S +85,1,2,"Ilett, Miss. Bertha",female,17,0,0,SO/C 14885,10.5,,S +86,1,3,"Backstrom, Mrs. Karl Alfred (Maria Mathilda Gustafsson)",female,33,3,0,3101278,15.85,,S +87,0,3,"Ford, Mr. William Neal",male,16,1,3,W./C. 6608,34.375,,S +88,0,3,"Slocovski, Mr. Selman Francis",male,,0,0,SOTON/OQ 392086,8.05,,S +89,1,1,"Fortune, Miss. Mabel Helen",female,23,3,2,19950,263,C23 C25 C27,S +90,0,3,"Celotti, Mr. Francesco",male,24,0,0,343275,8.05,,S +91,0,3,"Christmann, Mr. Emil",male,29,0,0,343276,8.05,,S +92,0,3,"Andreasson, Mr. Paul Edvin",male,20,0,0,347466,7.8542,,S +93,0,1,"Chaffee, Mr. Herbert Fuller",male,46,1,0,W.E.P. 5734,61.175,E31,S +94,0,3,"Dean, Mr. Bertram Frank",male,26,1,2,C.A. 2315,20.575,,S +95,0,3,"Coxon, Mr. Daniel",male,59,0,0,364500,7.25,,S +96,0,3,"Shorney, Mr. Charles Joseph",male,,0,0,374910,8.05,,S +97,0,1,"Goldschmidt, Mr. George B",male,71,0,0,PC 17754,34.6542,A5,C +98,1,1,"Greenfield, Mr. William Bertram",male,23,0,1,PC 17759,63.3583,D10 D12,C +99,1,2,"Doling, Mrs. John T (Ada Julia Bone)",female,34,0,1,231919,23,,S +100,0,2,"Kantor, Mr. Sinai",male,34,1,0,244367,26,,S +101,0,3,"Petranec, Miss. Matilda",female,28,0,0,349245,7.8958,,S +102,0,3,"Petroff, Mr. Pastcho (""Pentcho"")",male,,0,0,349215,7.8958,,S +103,0,1,"White, Mr. Richard Frasar",male,21,0,1,35281,77.2875,D26,S +104,0,3,"Johansson, Mr. Gustaf Joel",male,33,0,0,7540,8.6542,,S +105,0,3,"Gustafsson, Mr. Anders Vilhelm",male,37,2,0,3101276,7.925,,S +106,0,3,"Mionoff, Mr. Stoytcho",male,28,0,0,349207,7.8958,,S +107,1,3,"Salkjelsvik, Miss. Anna Kristine",female,21,0,0,343120,7.65,,S +108,1,3,"Moss, Mr. Albert Johan",male,,0,0,312991,7.775,,S +109,0,3,"Rekic, Mr. Tido",male,38,0,0,349249,7.8958,,S +110,1,3,"Moran, Miss. Bertha",female,,1,0,371110,24.15,,Q +111,0,1,"Porter, Mr. Walter Chamberlain",male,47,0,0,110465,52,C110,S +112,0,3,"Zabour, Miss. Hileni",female,14.5,1,0,2665,14.4542,,C +113,0,3,"Barton, Mr. David John",male,22,0,0,324669,8.05,,S +114,0,3,"Jussila, Miss. Katriina",female,20,1,0,4136,9.825,,S +115,0,3,"Attalah, Miss. Malake",female,17,0,0,2627,14.4583,,C +116,0,3,"Pekoniemi, Mr. Edvard",male,21,0,0,STON/O 2. 3101294,7.925,,S +117,0,3,"Connors, Mr. Patrick",male,70.5,0,0,370369,7.75,,Q +118,0,2,"Turpin, Mr. William John Robert",male,29,1,0,11668,21,,S +119,0,1,"Baxter, Mr. Quigg Edmond",male,24,0,1,PC 17558,247.5208,B58 B60,C +120,0,3,"Andersson, Miss. Ellis Anna Maria",female,2,4,2,347082,31.275,,S +121,0,2,"Hickman, Mr. Stanley George",male,21,2,0,S.O.C. 14879,73.5,,S +122,0,3,"Moore, Mr. Leonard Charles",male,,0,0,A4. 54510,8.05,,S +123,0,2,"Nasser, Mr. Nicholas",male,32.5,1,0,237736,30.0708,,C +124,1,2,"Webber, Miss. Susan",female,32.5,0,0,27267,13,E101,S +125,0,1,"White, Mr. Percival Wayland",male,54,0,1,35281,77.2875,D26,S +126,1,3,"Nicola-Yarred, Master. Elias",male,12,1,0,2651,11.2417,,C +127,0,3,"McMahon, Mr. Martin",male,,0,0,370372,7.75,,Q +128,1,3,"Madsen, Mr. Fridtjof Arne",male,24,0,0,C 17369,7.1417,,S +129,1,3,"Peter, Miss. Anna",female,,1,1,2668,22.3583,F E69,C +130,0,3,"Ekstrom, Mr. Johan",male,45,0,0,347061,6.975,,S +131,0,3,"Drazenoic, Mr. Jozef",male,33,0,0,349241,7.8958,,C +132,0,3,"Coelho, Mr. Domingos Fernandeo",male,20,0,0,SOTON/O.Q. 3101307,7.05,,S +133,0,3,"Robins, Mrs. Alexander A (Grace Charity Laury)",female,47,1,0,A/5. 3337,14.5,,S +134,1,2,"Weisz, Mrs. Leopold (Mathilde Francoise Pede)",female,29,1,0,228414,26,,S +135,0,2,"Sobey, Mr. Samuel James Hayden",male,25,0,0,C.A. 29178,13,,S +136,0,2,"Richard, Mr. Emile",male,23,0,0,SC/PARIS 2133,15.0458,,C +137,1,1,"Newsom, Miss. Helen Monypeny",female,19,0,2,11752,26.2833,D47,S +138,0,1,"Futrelle, Mr. Jacques Heath",male,37,1,0,113803,53.1,C123,S +139,0,3,"Osen, Mr. Olaf Elon",male,16,0,0,7534,9.2167,,S +140,0,1,"Giglio, Mr. Victor",male,24,0,0,PC 17593,79.2,B86,C +141,0,3,"Boulos, Mrs. Joseph (Sultana)",female,,0,2,2678,15.2458,,C +142,1,3,"Nysten, Miss. Anna Sofia",female,22,0,0,347081,7.75,,S +143,1,3,"Hakkarainen, Mrs. Pekka Pietari (Elin Matilda Dolck)",female,24,1,0,STON/O2. 3101279,15.85,,S +144,0,3,"Burke, Mr. Jeremiah",male,19,0,0,365222,6.75,,Q +145,0,2,"Andrew, Mr. Edgardo Samuel",male,18,0,0,231945,11.5,,S +146,0,2,"Nicholls, Mr. Joseph Charles",male,19,1,1,C.A. 33112,36.75,,S +147,1,3,"Andersson, Mr. August Edvard (""Wennerstrom"")",male,27,0,0,350043,7.7958,,S +148,0,3,"Ford, Miss. Robina Maggie 'Ruby'",female,9,2,2,W./C. 6608,34.375,,S +149,0,2,"Navratil, Mr. Michel (""Louis M Hoffman"")",male,36.5,0,2,230080,26,F2,S +150,0,2,"Byles, Rev. Thomas Roussel Davids",male,42,0,0,244310,13,,S +151,0,2,"Bateman, Rev. Robert James",male,51,0,0,S.O.P. 1166,12.525,,S +152,1,1,"Pears, Mrs. Thomas (Edith Wearne)",female,22,1,0,113776,66.6,C2,S +153,0,3,"Meo, Mr. Alfonzo",male,55.5,0,0,A.5. 11206,8.05,,S +154,0,3,"van Billiard, Mr. Austin Blyler",male,40.5,0,2,A/5. 851,14.5,,S +155,0,3,"Olsen, Mr. Ole Martin",male,,0,0,Fa 265302,7.3125,,S +156,0,1,"Williams, Mr. Charles Duane",male,51,0,1,PC 17597,61.3792,,C From 33403676f6834e8380631fdb581ec4154b681b52 Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:12:28 -0700 Subject: [PATCH 06/14] Unit3 Sprint 2 Challenge --- .../challenge.md | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 module4-acid-and-database-scalability-tradeoffs/challenge.md diff --git a/module4-acid-and-database-scalability-tradeoffs/challenge.md b/module4-acid-and-database-scalability-tradeoffs/challenge.md new file mode 100644 index 00000000..003aa386 --- /dev/null +++ b/module4-acid-and-database-scalability-tradeoffs/challenge.md @@ -0,0 +1,144 @@ +# Data Science Unit 3 Sprint Challenge 2 + +## Databases and SQL + +A SQL Query walks into a bar. In one corner of the bar are two tables. The Query +walks up to the tables and asks: + +... + +*"Mind if I join you?"* + +--- + +In this sprint challenge you will write code and answer questions related to +databases, with a focus on SQL but an acknowledgment of the broader ecosystem. +You may use any tools and references you wish, but your final code should +reflect *your* work and be saved in `.py` files (*not* notebooks), and (along +with this file including your written answers) turned in directly to your TL. + +For all your code, you may only import/use the following: +- other modules you write +- `sqlite3` (from the standard library) + +As always, make sure to manage your time - get a section/question to "good +enough" and then move on to make sure you do everything. You can always revisit +and polish at the end if time allows. + +This file is Markdown, so it may be helpful to open with VS Code or another tool +that allows you to view it nicely rendered. + +Good luck! + +### Part 1 - Making and populating a Database + +Consider the following data: + +| s | x | y | +|-----|---|---| +| 'g' | 3 | 9 | +| 'v' | 5 | 7 | +| 'f' | 8 | 7 | + +Using the standard `sqlite3` module: + +- Open a connection to a new (blank) database file `demo_data.sqlite3` +- Make a cursor, and execute an appropriate `CREATE TABLE` statement to accept + the above data (name the table `demo`) +- Write and execute appropriate `INSERT INTO` statements to add the data (as + shown above) to the database + +Make sure to `commit()` so your data is saved! The file size should be non-zero. + +Then write the following queries (also with `sqlite3`) to test: + +- Count how many rows you have - it should be 3! +- How many rows are there where both `x` and `y` are at least 5? +- How many unique values of `y` are there (hint - `COUNT()` can accept a keyword + `DISTINCT`)? + +Your code (to reproduce all above steps) should be saved in `demo_data.py` and +added to the repository along with the generated SQLite database. + +### Part 2 - The Northwind Database + +Using `sqlite3`, connect to the given `northwind_small.sqlite3` database. + +![Northwind Entity-Relationship Diagram](./northwind_erd.png) + +Above is an entity-relationship diagram - a picture summarizing the schema and +relationships in the database. Note that it was generated using Microsoft +Access, and some of the specific table/field names are different in the provided +data. You can see all the tables available to SQLite as follows: + +```python +>>> curs.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY +name;").fetchall() +[('Category',), ('Customer',), ('CustomerCustomerDemo',), +('CustomerDemographic',), ('Employee',), ('EmployeeTerritory',), ('Order',), +('OrderDetail',), ('Product',), ('Region',), ('Shipper',), ('Supplier',), +('Territory',)] +``` + +*Warning*: unlike the diagram, the tables in SQLite are singular and not plural +(do not end in `s`). And you can see the schema (`CREATE TABLE` statement) +behind any given table with: +```python +>>> curs.execute('SELECT sql FROM sqlite_master WHERE name="Customer";').fetchall() +[('CREATE TABLE "Customer" \n(\n "Id" VARCHAR(8000) PRIMARY KEY, \n +"CompanyName" VARCHAR(8000) NULL, \n "ContactName" VARCHAR(8000) NULL, \n +"ContactTitle" VARCHAR(8000) NULL, \n "Address" VARCHAR(8000) NULL, \n "City" +VARCHAR(8000) NULL, \n "Region" VARCHAR(8000) NULL, \n "PostalCode" +VARCHAR(8000) NULL, \n "Country" VARCHAR(8000) NULL, \n "Phone" VARCHAR(8000) +NULL, \n "Fax" VARCHAR(8000) NULL \n)',)] +``` + +In particular note that the *primary* key is `Id`, and not `CustomerId`. On +other tables (where it is a *foreign* key) it will be `CustomerId`. Also note - +the `Order` table conflicts with the `ORDER` keyword! We'll just avoid that +particular table, but it's a good lesson in the danger of keyword conflicts. + +Answer the following questions (each is from a single table): + +- What are the ten most expensive items (per unit price) in the database? +- What is the average age of an employee at the time of their hiring? (Hint: a + lot of arithmetic works with dates.) +- (*Stretch*) How does the average age of employee at hire vary by city? + +Your code (to load and query the data) should be saved in `northwind.py`, and +added to the repository. Do your best to answer in purely SQL, but if necessary +use Python/other logic to help. + +### Part 3 - Sailing the Northwind Seas + +You've answered some basic questions from the Northwind database, looking at +individual tables - now it's time to put things together, and `JOIN`! + +Using `sqlite3` in `northwind.py`, answer the following: + +- What are the ten most expensive items (per unit price) in the database *and* + their suppliers? +- What is the largest category (by number of unique products in it)? +- (*Stretch*) Who's the employee with the most territories? Use `TerritoryId` + (not name, region, or other fields) as the unique identifier for territories. + +### Part 4 - Questions (and your Answers) + +Answer the following questions, baseline ~3-5 sentences each, as if they were +interview screening questions (a form you fill when applying for a job): + +- In the Northwind database, what is the type of relationship between the + `Employee` and `Territory` tables? +- What is a situation where a document store (like MongoDB) is appropriate, and + what is a situation where it is not appropriate? +- What is "NewSQL", and what is it trying to achieve? + +### Part 5 - Turn it in! +Provide all the files you wrote (`demo_data.py`, `northwind.py`), as well as +this file with your answers to part 4, directly to your TL. You're also +encouraged to include the output from your queries as docstring comments, to +facilitate grading and feedback. Thanks for your hard work! + +If you got this far, check out the [larger Northwind +database](https://github.com/jpwhite3/northwind-SQLite3/blob/master/Northwind_large.sqlite.zip) - +your queries should run on it as well, with richer results. From 6a79d1bcd07eaa597f9b3a2647c4b1e4fc6c023a Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:21:06 -0700 Subject: [PATCH 07/14] Create Unit-3-Sprint-Challenge-2 --- Unit-3-Sprint-Challenge-2 | 1 + 1 file changed, 1 insertion(+) create mode 100644 Unit-3-Sprint-Challenge-2 diff --git a/Unit-3-Sprint-Challenge-2 b/Unit-3-Sprint-Challenge-2 new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Unit-3-Sprint-Challenge-2 @@ -0,0 +1 @@ + From 0b7f7337a116c7f07a14527aed1e74c7f0a808c2 Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:21:48 -0700 Subject: [PATCH 08/14] Delete Unit-3-Sprint-Challenge-2 --- Unit-3-Sprint-Challenge-2 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Unit-3-Sprint-Challenge-2 diff --git a/Unit-3-Sprint-Challenge-2 b/Unit-3-Sprint-Challenge-2 deleted file mode 100644 index 8b137891..00000000 --- a/Unit-3-Sprint-Challenge-2 +++ /dev/null @@ -1 +0,0 @@ - From 5c469115c30c1b4a92aef386620650a65a2db17d Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:29:25 -0700 Subject: [PATCH 09/14] Delete challenge.md --- .../challenge.md | 144 ------------------ 1 file changed, 144 deletions(-) delete mode 100644 module4-acid-and-database-scalability-tradeoffs/challenge.md diff --git a/module4-acid-and-database-scalability-tradeoffs/challenge.md b/module4-acid-and-database-scalability-tradeoffs/challenge.md deleted file mode 100644 index 003aa386..00000000 --- a/module4-acid-and-database-scalability-tradeoffs/challenge.md +++ /dev/null @@ -1,144 +0,0 @@ -# Data Science Unit 3 Sprint Challenge 2 - -## Databases and SQL - -A SQL Query walks into a bar. In one corner of the bar are two tables. The Query -walks up to the tables and asks: - -... - -*"Mind if I join you?"* - ---- - -In this sprint challenge you will write code and answer questions related to -databases, with a focus on SQL but an acknowledgment of the broader ecosystem. -You may use any tools and references you wish, but your final code should -reflect *your* work and be saved in `.py` files (*not* notebooks), and (along -with this file including your written answers) turned in directly to your TL. - -For all your code, you may only import/use the following: -- other modules you write -- `sqlite3` (from the standard library) - -As always, make sure to manage your time - get a section/question to "good -enough" and then move on to make sure you do everything. You can always revisit -and polish at the end if time allows. - -This file is Markdown, so it may be helpful to open with VS Code or another tool -that allows you to view it nicely rendered. - -Good luck! - -### Part 1 - Making and populating a Database - -Consider the following data: - -| s | x | y | -|-----|---|---| -| 'g' | 3 | 9 | -| 'v' | 5 | 7 | -| 'f' | 8 | 7 | - -Using the standard `sqlite3` module: - -- Open a connection to a new (blank) database file `demo_data.sqlite3` -- Make a cursor, and execute an appropriate `CREATE TABLE` statement to accept - the above data (name the table `demo`) -- Write and execute appropriate `INSERT INTO` statements to add the data (as - shown above) to the database - -Make sure to `commit()` so your data is saved! The file size should be non-zero. - -Then write the following queries (also with `sqlite3`) to test: - -- Count how many rows you have - it should be 3! -- How many rows are there where both `x` and `y` are at least 5? -- How many unique values of `y` are there (hint - `COUNT()` can accept a keyword - `DISTINCT`)? - -Your code (to reproduce all above steps) should be saved in `demo_data.py` and -added to the repository along with the generated SQLite database. - -### Part 2 - The Northwind Database - -Using `sqlite3`, connect to the given `northwind_small.sqlite3` database. - -![Northwind Entity-Relationship Diagram](./northwind_erd.png) - -Above is an entity-relationship diagram - a picture summarizing the schema and -relationships in the database. Note that it was generated using Microsoft -Access, and some of the specific table/field names are different in the provided -data. You can see all the tables available to SQLite as follows: - -```python ->>> curs.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY -name;").fetchall() -[('Category',), ('Customer',), ('CustomerCustomerDemo',), -('CustomerDemographic',), ('Employee',), ('EmployeeTerritory',), ('Order',), -('OrderDetail',), ('Product',), ('Region',), ('Shipper',), ('Supplier',), -('Territory',)] -``` - -*Warning*: unlike the diagram, the tables in SQLite are singular and not plural -(do not end in `s`). And you can see the schema (`CREATE TABLE` statement) -behind any given table with: -```python ->>> curs.execute('SELECT sql FROM sqlite_master WHERE name="Customer";').fetchall() -[('CREATE TABLE "Customer" \n(\n "Id" VARCHAR(8000) PRIMARY KEY, \n -"CompanyName" VARCHAR(8000) NULL, \n "ContactName" VARCHAR(8000) NULL, \n -"ContactTitle" VARCHAR(8000) NULL, \n "Address" VARCHAR(8000) NULL, \n "City" -VARCHAR(8000) NULL, \n "Region" VARCHAR(8000) NULL, \n "PostalCode" -VARCHAR(8000) NULL, \n "Country" VARCHAR(8000) NULL, \n "Phone" VARCHAR(8000) -NULL, \n "Fax" VARCHAR(8000) NULL \n)',)] -``` - -In particular note that the *primary* key is `Id`, and not `CustomerId`. On -other tables (where it is a *foreign* key) it will be `CustomerId`. Also note - -the `Order` table conflicts with the `ORDER` keyword! We'll just avoid that -particular table, but it's a good lesson in the danger of keyword conflicts. - -Answer the following questions (each is from a single table): - -- What are the ten most expensive items (per unit price) in the database? -- What is the average age of an employee at the time of their hiring? (Hint: a - lot of arithmetic works with dates.) -- (*Stretch*) How does the average age of employee at hire vary by city? - -Your code (to load and query the data) should be saved in `northwind.py`, and -added to the repository. Do your best to answer in purely SQL, but if necessary -use Python/other logic to help. - -### Part 3 - Sailing the Northwind Seas - -You've answered some basic questions from the Northwind database, looking at -individual tables - now it's time to put things together, and `JOIN`! - -Using `sqlite3` in `northwind.py`, answer the following: - -- What are the ten most expensive items (per unit price) in the database *and* - their suppliers? -- What is the largest category (by number of unique products in it)? -- (*Stretch*) Who's the employee with the most territories? Use `TerritoryId` - (not name, region, or other fields) as the unique identifier for territories. - -### Part 4 - Questions (and your Answers) - -Answer the following questions, baseline ~3-5 sentences each, as if they were -interview screening questions (a form you fill when applying for a job): - -- In the Northwind database, what is the type of relationship between the - `Employee` and `Territory` tables? -- What is a situation where a document store (like MongoDB) is appropriate, and - what is a situation where it is not appropriate? -- What is "NewSQL", and what is it trying to achieve? - -### Part 5 - Turn it in! -Provide all the files you wrote (`demo_data.py`, `northwind.py`), as well as -this file with your answers to part 4, directly to your TL. You're also -encouraged to include the output from your queries as docstring comments, to -facilitate grading and feedback. Thanks for your hard work! - -If you got this far, check out the [larger Northwind -database](https://github.com/jpwhite3/northwind-SQLite3/blob/master/Northwind_large.sqlite.zip) - -your queries should run on it as well, with richer results. From 27f75616b66211d5c678af1b03276938e5ecf913 Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:30:43 -0700 Subject: [PATCH 10/14] Create Unit3-Sprint-Challenge-2 --- Unit3-Sprint-Challenge-2 | 1 + 1 file changed, 1 insertion(+) create mode 100644 Unit3-Sprint-Challenge-2 diff --git a/Unit3-Sprint-Challenge-2 b/Unit3-Sprint-Challenge-2 new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Unit3-Sprint-Challenge-2 @@ -0,0 +1 @@ + From c26f87410975a21e13dcf1b1aec5b27bab392554 Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:31:33 -0700 Subject: [PATCH 11/14] Delete Unit3-Sprint-Challenge-2 --- Unit3-Sprint-Challenge-2 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Unit3-Sprint-Challenge-2 diff --git a/Unit3-Sprint-Challenge-2 b/Unit3-Sprint-Challenge-2 deleted file mode 100644 index 8b137891..00000000 --- a/Unit3-Sprint-Challenge-2 +++ /dev/null @@ -1 +0,0 @@ - From e6a782be657f5fcc0b2dfdf70fdb48c09b7becf9 Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:36:45 -0700 Subject: [PATCH 12/14] Create .gitkeep --- Unit-3-Sprint-Challenge-2/.gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 Unit-3-Sprint-Challenge-2/.gitkeep diff --git a/Unit-3-Sprint-Challenge-2/.gitkeep b/Unit-3-Sprint-Challenge-2/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Unit-3-Sprint-Challenge-2/.gitkeep @@ -0,0 +1 @@ + From 4fdb25f5cce4f7c80fdf2aad7e1d77aa840ff401 Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:37:03 -0700 Subject: [PATCH 13/14] Add files via upload --- Unit-3-Sprint-Challenge-2/challenge.md | 144 +++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 Unit-3-Sprint-Challenge-2/challenge.md diff --git a/Unit-3-Sprint-Challenge-2/challenge.md b/Unit-3-Sprint-Challenge-2/challenge.md new file mode 100644 index 00000000..003aa386 --- /dev/null +++ b/Unit-3-Sprint-Challenge-2/challenge.md @@ -0,0 +1,144 @@ +# Data Science Unit 3 Sprint Challenge 2 + +## Databases and SQL + +A SQL Query walks into a bar. In one corner of the bar are two tables. The Query +walks up to the tables and asks: + +... + +*"Mind if I join you?"* + +--- + +In this sprint challenge you will write code and answer questions related to +databases, with a focus on SQL but an acknowledgment of the broader ecosystem. +You may use any tools and references you wish, but your final code should +reflect *your* work and be saved in `.py` files (*not* notebooks), and (along +with this file including your written answers) turned in directly to your TL. + +For all your code, you may only import/use the following: +- other modules you write +- `sqlite3` (from the standard library) + +As always, make sure to manage your time - get a section/question to "good +enough" and then move on to make sure you do everything. You can always revisit +and polish at the end if time allows. + +This file is Markdown, so it may be helpful to open with VS Code or another tool +that allows you to view it nicely rendered. + +Good luck! + +### Part 1 - Making and populating a Database + +Consider the following data: + +| s | x | y | +|-----|---|---| +| 'g' | 3 | 9 | +| 'v' | 5 | 7 | +| 'f' | 8 | 7 | + +Using the standard `sqlite3` module: + +- Open a connection to a new (blank) database file `demo_data.sqlite3` +- Make a cursor, and execute an appropriate `CREATE TABLE` statement to accept + the above data (name the table `demo`) +- Write and execute appropriate `INSERT INTO` statements to add the data (as + shown above) to the database + +Make sure to `commit()` so your data is saved! The file size should be non-zero. + +Then write the following queries (also with `sqlite3`) to test: + +- Count how many rows you have - it should be 3! +- How many rows are there where both `x` and `y` are at least 5? +- How many unique values of `y` are there (hint - `COUNT()` can accept a keyword + `DISTINCT`)? + +Your code (to reproduce all above steps) should be saved in `demo_data.py` and +added to the repository along with the generated SQLite database. + +### Part 2 - The Northwind Database + +Using `sqlite3`, connect to the given `northwind_small.sqlite3` database. + +![Northwind Entity-Relationship Diagram](./northwind_erd.png) + +Above is an entity-relationship diagram - a picture summarizing the schema and +relationships in the database. Note that it was generated using Microsoft +Access, and some of the specific table/field names are different in the provided +data. You can see all the tables available to SQLite as follows: + +```python +>>> curs.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY +name;").fetchall() +[('Category',), ('Customer',), ('CustomerCustomerDemo',), +('CustomerDemographic',), ('Employee',), ('EmployeeTerritory',), ('Order',), +('OrderDetail',), ('Product',), ('Region',), ('Shipper',), ('Supplier',), +('Territory',)] +``` + +*Warning*: unlike the diagram, the tables in SQLite are singular and not plural +(do not end in `s`). And you can see the schema (`CREATE TABLE` statement) +behind any given table with: +```python +>>> curs.execute('SELECT sql FROM sqlite_master WHERE name="Customer";').fetchall() +[('CREATE TABLE "Customer" \n(\n "Id" VARCHAR(8000) PRIMARY KEY, \n +"CompanyName" VARCHAR(8000) NULL, \n "ContactName" VARCHAR(8000) NULL, \n +"ContactTitle" VARCHAR(8000) NULL, \n "Address" VARCHAR(8000) NULL, \n "City" +VARCHAR(8000) NULL, \n "Region" VARCHAR(8000) NULL, \n "PostalCode" +VARCHAR(8000) NULL, \n "Country" VARCHAR(8000) NULL, \n "Phone" VARCHAR(8000) +NULL, \n "Fax" VARCHAR(8000) NULL \n)',)] +``` + +In particular note that the *primary* key is `Id`, and not `CustomerId`. On +other tables (where it is a *foreign* key) it will be `CustomerId`. Also note - +the `Order` table conflicts with the `ORDER` keyword! We'll just avoid that +particular table, but it's a good lesson in the danger of keyword conflicts. + +Answer the following questions (each is from a single table): + +- What are the ten most expensive items (per unit price) in the database? +- What is the average age of an employee at the time of their hiring? (Hint: a + lot of arithmetic works with dates.) +- (*Stretch*) How does the average age of employee at hire vary by city? + +Your code (to load and query the data) should be saved in `northwind.py`, and +added to the repository. Do your best to answer in purely SQL, but if necessary +use Python/other logic to help. + +### Part 3 - Sailing the Northwind Seas + +You've answered some basic questions from the Northwind database, looking at +individual tables - now it's time to put things together, and `JOIN`! + +Using `sqlite3` in `northwind.py`, answer the following: + +- What are the ten most expensive items (per unit price) in the database *and* + their suppliers? +- What is the largest category (by number of unique products in it)? +- (*Stretch*) Who's the employee with the most territories? Use `TerritoryId` + (not name, region, or other fields) as the unique identifier for territories. + +### Part 4 - Questions (and your Answers) + +Answer the following questions, baseline ~3-5 sentences each, as if they were +interview screening questions (a form you fill when applying for a job): + +- In the Northwind database, what is the type of relationship between the + `Employee` and `Territory` tables? +- What is a situation where a document store (like MongoDB) is appropriate, and + what is a situation where it is not appropriate? +- What is "NewSQL", and what is it trying to achieve? + +### Part 5 - Turn it in! +Provide all the files you wrote (`demo_data.py`, `northwind.py`), as well as +this file with your answers to part 4, directly to your TL. You're also +encouraged to include the output from your queries as docstring comments, to +facilitate grading and feedback. Thanks for your hard work! + +If you got this far, check out the [larger Northwind +database](https://github.com/jpwhite3/northwind-SQLite3/blob/master/Northwind_large.sqlite.zip) - +your queries should run on it as well, with richer results. From 5b520179e88984d78bd36967cb48962f519e2037 Mon Sep 17 00:00:00 2001 From: nusc2016 <61950417+nusc2016@users.noreply.github.com> Date: Fri, 12 Jun 2020 08:37:56 -0700 Subject: [PATCH 14/14] Add files via upload --- Unit-3-Sprint-Challenge-2/northwind_erd.png | Bin 0 -> 88732 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Unit-3-Sprint-Challenge-2/northwind_erd.png diff --git a/Unit-3-Sprint-Challenge-2/northwind_erd.png b/Unit-3-Sprint-Challenge-2/northwind_erd.png new file mode 100644 index 0000000000000000000000000000000000000000..7288c24ee21b41013fdd5f2d45a4e94372a7f0f6 GIT binary patch literal 88732 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 literal 0 HcmV?d00001