From 3d99e7579d74e268d52b11ce3770c0c5bb642225 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Thu, 9 May 2019 16:07:02 -0500 Subject: [PATCH 01/11] add Filepath.ipynb --- notebooks/Filepaths.ipynb | 883 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 883 insertions(+) create mode 100644 notebooks/Filepaths.ipynb diff --git a/notebooks/Filepaths.ipynb b/notebooks/Filepaths.ipynb new file mode 100644 index 0000000..88ac8c9 --- /dev/null +++ b/notebooks/Filepaths.ipynb @@ -0,0 +1,883 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython import display\n", + "from ipywidgets import Image\n", + "\n", + "import os\n", + "import datajoint as dj" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dimitri@localhost:3306\n" + ] + } + ], + "source": [ + "schema = dj.schema('test_filepath')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "## Storage configuration\n", + "\n", + "# set up stores\n", + "dj.config['stores'] = {\n", + " 'remote': dict( # store in minio\n", + " stage=os.path.abspath('./stage'),\n", + " protocol='s3',\n", + " endpoint='localhost:9000',\n", + " access_key='datajoint',\n", + " secret_key='datajoint',\n", + " bucket='datajoint-demo', \n", + " location='dj/file-demo'), \n", + " }" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Download some images off the web into ./stage" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Step 1: Find a bunch of images on the web\n", + "logos = dict(\n", + " ucsd='https://upload.wikimedia.org/wikipedia/commons/f/f6/UCSD_logo.png',\n", + " datajoint='https://datajoint.io/static/images/DJiotitle.png',\n", + " utah='https://umc.utah.edu/wp-content/uploads/sites/15/2015/01/Ulogo_400p.png',\n", + " bcm='https://upload.wikimedia.org/wikipedia/commons/5/5d/Baylor_College_of_Medicine_Logo.png',\n", + " pydata='https://pydata.org/wp-content/uploads/2018/10/pydata-logo.png',\n", + " python='https://www.python.org/static/community_logos/python-logo-master-v3-TM.png',\n", + " pni='https://vathes.com/2018/05/24/Princeton-Neuroscience-Institute-Partners-with-Vathes-to-Support-the-Adoption-of-DataJoint/PNI%20logo.png')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Organization(dj.Lookup):\n", + " definition = \"\"\"\n", + " organization : varchar(30)\n", + " --- \n", + " logo_url : varchar(255)\n", + " \"\"\"\n", + " contents = logos.items()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "
\n", + "

organization

\n", + " \n", + "
\n", + "

logo_url

\n", + " \n", + "
bcmhttps://upload.wikimedia.org/wikipedia/commons/5/5d/Baylor_College_of_Medicine_Logo.png
datajointhttps://datajoint.io/static/images/DJiotitle.png
pnihttps://vathes.com/2018/05/24/Princeton-Neuroscience-Institute-Partners-with-Vathes-to-Support-the-Adoption-of-DataJoint/PNI%20logo.png
\n", + "

...

\n", + "

Total: 7

\n", + " " + ], + "text/plain": [ + "*organization logo_url \n", + "+------------+ +------------+\n", + "bcm https://upload\n", + "datajoint https://datajo\n", + "pni https://vathes\n", + " ...\n", + " (Total: 7)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Organization()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "import requests \n", + "\n", + "@schema\n", + "class Logo(dj.Imported):\n", + " definition = \"\"\"\n", + " -> Organization\n", + " ---\n", + " logo_image : filepath@remote\n", + " \"\"\"\n", + " \n", + " path = os.path.join(dj.config['stores']['remote']['stage'], 'organizations', 'logos')\n", + " \n", + " def make(self, key):\n", + " os.makedirs(self.path, exist_ok=True)\n", + " url = (Organization & key).fetch1('logo_url')\n", + " local_file = os.path.join(self.path, key['organization'] + os.path.splitext(url)[1])\n", + " print(local_file)\n", + " with open(local_file, 'wb') as f:\n", + " f.write(requests.get(url).content)\n", + " self.insert1(dict(key, logo_image=local_file)) " + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png\n" + ] + } + ], + "source": [ + "Logo.populate()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "
\n", + "

organization

\n", + " \n", + "
\n", + "

logo_image

\n", + " \n", + "
pydata=BLOB=
utah=BLOB=
datajoint=BLOB=
\n", + "

...

\n", + "

Total: 7

\n", + " " + ], + "text/plain": [ + "*organization logo_image\n", + "+------------+ +--------+\n", + "pydata =BLOB= \n", + "utah =BLOB= \n", + "datajoint =BLOB= \n", + " ...\n", + " (Total: 7)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Logo()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'organization': 'pydata',\n", + " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pydata.png'},\n", + " {'organization': 'utah',\n", + " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/utah.png'},\n", + " {'organization': 'datajoint',\n", + " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png'},\n", + " {'organization': 'ucsd',\n", + " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/ucsd.png'},\n", + " {'organization': 'pni',\n", + " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pni.png'},\n", + " {'organization': 'python',\n", + " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/python.png'},\n", + " {'organization': 'bcm',\n", + " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png'}]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Logo.fetch(as_dict=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# delete the local repository completely\n", + "import shutil\n", + "shutil.rmtree(dj.config['stores']['remote']['stage'])" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "paths = Logo().fetch('logo_image')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pydata.png',\n", + " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/utah.png',\n", + " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png',\n", + " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/ucsd.png',\n", + " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pni.png',\n", + " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/python.png',\n", + " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png'],\n", + " dtype=object)" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "paths" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "004ccb36b6a34dc48e961db8724db181", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Image(value=b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR\\x00\\x00\\x02Y\\x00\\x00\\x00\\xcb\\x08\\x06\\x00\\x00\\x00]\\xc9\\x86&\\x…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Image.from_file(paths[5])" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "About to delete:\n", + "`test_filepath`.`_logo`: 2 items\n", + "Proceed? [yes, No]: yes\n", + "Committed.\n" + ] + } + ], + "source": [ + "(Logo & 'organization in (\"datajoint\", \"bcm\")').delete()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "ext = schema.external['remote']" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Deleted 2 items\n" + ] + } + ], + "source": [ + "ext.delete()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Finding untracking files...\n", + "Deleting...\n", + "Done\n" + ] + } + ], + "source": [ + "ext.clean_filepaths()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(ext.get_untracked_filepaths())" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "states = dict(\n", + " AL='Alabama', AK='Alaska', AZ='Arizona', AR='Arkansas',\n", + " CA='California', CO='Colorado', CT='Connecticut', DE='Delaware',\n", + " FL='Florida', GA='Georgia', HI='Hawaii', ID='Idaho', \n", + " IL='Illinois', IN='Indiana', IA='Iowa', KS='Kansas',\n", + " KY='Kentucky', LA='Louisiana', ME='Maine', MD='Maryland',\n", + " MA='Massachusetts', MI='Michigan', MN='Minnesota', MS='Mississippi',\n", + " MO='Missouri', MT='Montana', NE='Nebraska', NV='Nevada',\n", + " NH='New Hampshire', NJ='New Jersey', NM='New Mexico', NY='New York',\n", + " NC='North Carolina', ND='North Dakota', OH='Ohio', OK='Oklahoma',\n", + " OR='Oregon', PA='Pennsylvania', RI='Rhode Island', SC='South Carlina',\n", + " SD='South Dakota', TN='Tennessee', TX='Texas', UT='Utah',\n", + " VT='Vermont', VA='Virginia', WA='Washington', WV='West Virginia', \n", + " WI='Wisconsin', WY='Wyoming')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class State(dj.Lookup):\n", + " definition = \"\"\"\n", + " # United States\n", + " state_code : char(2)\n", + " ---\n", + " state : varchar(20)\n", + " \"\"\"\n", + " contents = states.items()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " United States\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "
\n", + "

state_code

\n", + " \n", + "
\n", + "

state

\n", + " \n", + "
AKAlaska
ALAlabama
ARArkansas
\n", + "

...

\n", + "

Total: 50

\n", + " " + ], + "text/plain": [ + "*state_code state \n", + "+------------+ +----------+\n", + "AK Alaska \n", + "AL Alabama \n", + "AR Arkansas \n", + " ...\n", + " (Total: 50)" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "State()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class StateBird(dj.Imported):\n", + " definition = \"\"\"\n", + " -> State\n", + " ---\n", + " bird_image : filepath@remote \n", + " \"\"\"\n", + " path = os.path.join(dj.config['stores']['remote']['stage'], 'states', 'birds')\n", + " \n", + " \n", + " def make(self, key):\n", + " os.makedirs(self.path, exist_ok=True)\n", + " state = (State & key).fetch1('state')\n", + " url = \"http://www.theus50.com/images/state-birds/{state}-bird.jpg\".format(state=state.lower())\n", + " local_file = os.path.join(self.path, state.lower() + os.path.splitext(url)[1])\n", + " print(local_file)\n", + " with open(local_file, 'wb') as f:\n", + " f.write(requests.get(url).content)\n", + " self.insert1(dict(key, bird_image=local_file)) \n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/alaska.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/alabama.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/arkansas.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/arizona.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/california.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/colorado.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/connecticut.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/delaware.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/florida.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/georgia.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/hawaii.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/iowa.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/idaho.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/illinois.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/indiana.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/kansas.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/kentucky.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/louisiana.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/massachusetts.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/maryland.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/maine.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/michigan.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/minnesota.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/missouri.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/mississippi.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/montana.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/north carolina.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/north dakota.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/nebraska.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/new hampshire.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/new jersey.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/new mexico.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/nevada.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/new york.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/ohio.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/oklahoma.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/oregon.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/pennsylvania.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/rhode island.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/south carlina.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/south dakota.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/tennessee.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/texas.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/utah.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/virginia.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/vermont.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/washington.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/wisconsin.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/west virginia.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/birds/wyoming.jpg\n" + ] + } + ], + "source": [ + "StateBird.populate()" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class StateFlower(dj.Imported):\n", + " definition = \"\"\"\n", + " -> State\n", + " ---\n", + " flower_image : filepath@remote \n", + " \"\"\"\n", + " path = os.path.join(dj.config['stores']['remote']['stage'],'states', 'flowers')\n", + " \n", + " \n", + " def make(self, key):\n", + " os.makedirs(self.path, exist_ok=True)\n", + " state = (State & key).fetch1('state')\n", + " url = \"http://www.theus50.com/images/state-birds/{state}-flower.jpg\".format(state=state.lower())\n", + " local_file = os.path.join(self.path, state.lower() + os.path.splitext(url)[1])\n", + " print(local_file)\n", + " with open(local_file, 'wb') as f:\n", + " f.write(requests.get(url).content)\n", + " self.insert1(dict(key, flower_image=local_file)) " + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/alaska.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/alabama.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/arkansas.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/arizona.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/california.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/colorado.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/connecticut.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/delaware.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/florida.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/georgia.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/hawaii.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/iowa.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/idaho.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/illinois.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/indiana.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/kansas.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/kentucky.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/louisiana.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/massachusetts.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/maryland.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/maine.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/michigan.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/minnesota.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/missouri.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/mississippi.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/montana.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/north carolina.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/north dakota.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/nebraska.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/new hampshire.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/new jersey.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/new mexico.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/nevada.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/new york.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/ohio.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/oklahoma.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/oregon.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/pennsylvania.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/rhode island.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/south carlina.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/south dakota.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/tennessee.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/texas.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/utah.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/virginia.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/vermont.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/washington.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/wisconsin.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/west virginia.jpg\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/states/flowers/wyoming.jpg\n" + ] + } + ], + "source": [ + "StateFlower().populate()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dj.Diagram(schema)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 3d3f211d43d02ae5dd21d18229b5e8300c874c33 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Tue, 14 May 2019 10:24:13 -0500 Subject: [PATCH 02/11] add Improvements.ipynb for IBL queries --- notebooks/Improvements.ipynb | 868 +++++++++++++++++++++++++++++++++++ 1 file changed, 868 insertions(+) create mode 100644 notebooks/Improvements.ipynb diff --git a/notebooks/Improvements.ipynb b/notebooks/Improvements.ipynb new file mode 100644 index 0000000..bd442eb --- /dev/null +++ b/notebooks/Improvements.ipynb @@ -0,0 +1,868 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# This notebook demonstrates some improvements of queries from the IBL notebook" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dimitri@datajoint.internationalbrainlab.org:3306\n" + ] + } + ], + "source": [ + "import datajoint as dj\n", + "reference = dj.create_virtual_module('reference', 'ibl_dj_reference')\n", + "subject = dj.create_virtual_module('subject', 'ibl_dj_subject')\n", + "action = dj.create_virtual_module('action', 'ibl_dj_action')\n", + "acquisition = dj.create_virtual_module('acquisition', 'ibl_dj_acquisition')\n", + "data = dj.create_virtual_module('data', 'ibl_dj_data')\n", + "behavior = dj.create_virtual_module('behavior', 'ibl_dj_behavior')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ORIGINAL: \n", + "\n", + "# FIND THE DATA WE NEED\n", + "# FIRST, WHICH SUBJECTS ARE DOING THIS CA EXPERIMENT?\n", + "subj = (subject.Subject() - subject.Death & 'subject_birth_date < \"2018-09-01\"').proj('subject_nickname', 'sex') * \\\n", + " (subject.SubjectLab() & 'lab_name=\"churchlandlab\"').proj()\n", + "print(subj)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

subject_uuid

\n", + " \n", + "
\n", + "

subject_nickname

\n", + " nickname\n", + "
\n", + "

sex

\n", + " sex\n", + "
034c07c5-69b0-48c7-ab3e-e491e4dbb725IBL_25M
1208c089-8b8e-4a87-98f0-05a68fb18370IBL_13M
278bf922-073e-4ef4-90b5-ccf4e25e08feIBL_26M
3e97e1d3-2a0f-44e5-b63f-36196d78457aIBL_34M
3f854f88-7879-4368-9e0d-41edea3bfab9IBL_11M
52a800fc-cbbc-45e9-97b1-ad6f6166e9afIBL_1M
55381f61-4e47-4baa-beb9-70068c0ad62cIBL_46M
56b81bb0-fffb-4875-9cd6-29465782fb0eIBL_24M
64ff6fea-89a5-449d-a9f4-53f4b200e7dbIBL_20M
6af88109-8b3d-485c-8486-f8b35d2bf061IBL_23M
7c751b49-55a6-4eac-9bdb-367faf2a18eeIBL_10M
a7ccdd67-8443-458a-a0ba-2f76a826a7a7IBL_21M
\n", + "

...

\n", + "

Total: 15

\n", + " " + ], + "text/plain": [ + "*subject_uuid subject_nickna sex \n", + "+------------+ +------------+ +-----+\n", + "034c07c5-69b0- IBL_25 M \n", + "1208c089-8b8e- IBL_13 M \n", + "278bf922-073e- IBL_26 M \n", + "3e97e1d3-2a0f- IBL_34 M \n", + "3f854f88-7879- IBL_11 M \n", + "52a800fc-cbbc- IBL_1 M \n", + "55381f61-4e47- IBL_46 M \n", + "56b81bb0-fffb- IBL_24 M \n", + "64ff6fea-89a5- IBL_20 M \n", + "6af88109-8b3d- IBL_23 M \n", + "7c751b49-55a6- IBL_10 M \n", + "a7ccdd67-8443- IBL_21 M \n", + " ...\n", + " (Total: 15)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# IMPROVED: \n", + "subj = (subject.Subject * subject.SubjectLab - subject.Death & 'subject_birth_date < \"2018-09-01\"' & \n", + " {'lab_name': 'churchlandlab'}).proj('subject_nickname', 'sex')\n", + "subj" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ORIGINAL \n", + "\n", + "# get date for each weighing\n", + "weight_with_date = action.Weighing.proj('weight', session_date='DATE(weighing_time)')\n", + "# create a table with primary key to be the combination of subject_uuid and session_date\n", + "# dj.U, U means uniform, all possible combinations of subject uuid and session_date, when\n", + "# restricted with weight_with_date, it returns all existing combinations of subject_uuid and \n", + "# session_date in the table weight_with_date\n", + "# Note that there are more entries in weight_with_date than in weight_date, indicating there\n", + "# exists more than one weighing for some dates.\n", + "weight_date = (dj.U('subject_uuid', 'session_date') & weight_with_date)\n", + "\n", + "\n", + "# Aggregation to get average weight for each date\n", + "# before .aggr is the table you want aggregate, basically you get one value for each entry in \n", + "# weight_with_date\n", + "# first argument is the table that is useful to compute the value you need, here weight_with_date\n", + "# provides all weights for each date, 'weight' is an attribute in the table weight_with_date\n", + "# note that the results have the same number of entries as weight_date\n", + "avg_weight_date = weight_date.aggr(weight_with_date, avg_weight='AVG(weight)')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

subject_uuid

\n", + " \n", + "
\n", + "

session_date

\n", + " calculated attribute\n", + "
\n", + "

avg_weight

\n", + " calculated attribute\n", + "
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-07-2323.809999465942383
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-07-2423.299999237060547
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-07-2523.770000457763672
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-07-2623.350000381469727
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-07-2723.389999389648438
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-07-3022.200000762939453
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-07-3122.139999389648438
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-08-0122.239999771118164
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-08-0222.1200008392334
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-08-0322.360000610351562
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-08-0622.489999771118164
0026c82d-39e4-4c6b-acb3-303eb4b24f052018-08-0722.290000915527344
\n", + "

...

\n", + "

Total: 7898

\n", + " " + ], + "text/plain": [ + "*subject_uuid *session_date avg_weight \n", + "+------------+ +------------+ +------------+\n", + "0026c82d-39e4- 2018-07-23 23.80999946594\n", + "0026c82d-39e4- 2018-07-24 23.29999923706\n", + "0026c82d-39e4- 2018-07-25 23.77000045776\n", + "0026c82d-39e4- 2018-07-26 23.35000038146\n", + "0026c82d-39e4- 2018-07-27 23.38999938964\n", + "0026c82d-39e4- 2018-07-30 22.20000076293\n", + "0026c82d-39e4- 2018-07-31 22.13999938964\n", + "0026c82d-39e4- 2018-08-01 22.23999977111\n", + "0026c82d-39e4- 2018-08-02 22.12000083923\n", + "0026c82d-39e4- 2018-08-03 22.36000061035\n", + "0026c82d-39e4- 2018-08-06 22.48999977111\n", + "0026c82d-39e4- 2018-08-07 22.29000091552\n", + " ...\n", + " (Total: 7898)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# IMPROVED:\n", + "\n", + "weight_date = action.Weighing.proj('weight', session_date='DATE(weighing_time)')\n", + "avg_weight_date = dj.U('subject_uuid', 'session_date').aggr(weight_date, avg_weight='AVG(weight)')\n", + "avg_weight_date" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ORIGINAL\n", + "\n", + "# NOW DO THE SAME FOR WATER\n", + "water_with_date = action.WaterAdministration.proj('watertype_name', 'water_administered', 'adlib', \n", + " session_date='DATE(administration_time)')\n", + "water_date = (dj.U('subject_uuid', 'session_date') & water_with_date)\n", + "total_water_date = water_date.aggr(water_with_date, total_water='SUM(water_administered)', \n", + " watertype=\"GROUP_CONCAT(DISTINCT watertype_name SEPARATOR '; ')\", \n", + " adlib='MAX(adlib)')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

subject_uuid

\n", + " \n", + "
\n", + "

session_date

\n", + " calculated attribute\n", + "
\n", + "

total_water

\n", + " calculated attribute\n", + "
\n", + "

watertype

\n", + " calculated attribute\n", + "
\n", + "

adlib

\n", + " calculated attribute\n", + "
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-02-191.2780000269412994Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-02-210.7230999991297722Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-061.0Water0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-071.0Water0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-080.553600013256073Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-090.16830000281333923Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-110.5508000254631042Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-120.5669999718666077Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-131.617300033569336Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-140.36000001430511475Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-151.9387999773025513Water 10% Sucrose0
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-181.5479999780654907Water 10% Sucrose0
\n", + "

...

\n", + "

Total: 6421

\n", + " " + ], + "text/plain": [ + "*subject_uuid *session_date total_water watertype adlib \n", + "+------------+ +------------+ +------------+ +------------+ +-------+\n", + "00c60db3-74c3- 2019-02-19 1.278000026941 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-02-21 0.723099999129 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-03-06 1.0 Water 0 \n", + "00c60db3-74c3- 2019-03-07 1.0 Water 0 \n", + "00c60db3-74c3- 2019-03-08 0.553600013256 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-03-09 0.168300002813 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-03-11 0.550800025463 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-03-12 0.566999971866 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-03-13 1.617300033569 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-03-14 0.360000014305 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-03-15 1.938799977302 Water 10% Sucr 0 \n", + "00c60db3-74c3- 2019-03-18 1.547999978065 Water 10% Sucr 0 \n", + " ...\n", + " (Total: 6421)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# IMPROVED\n", + "\n", + "water_with_date = action.WaterAdministration.proj('watertype_name', 'water_administered', 'adlib', \n", + " session_date='DATE(administration_time)')\n", + "total_water_date = dj.U('subject_uuid', 'session_date').aggr(\n", + " water_with_date, \n", + " total_water='SUM(water_administered)', \n", + " watertype=\"GROUP_CONCAT(DISTINCT watertype_name SEPARATOR '; ')\", \n", + " adlib='MAX(adlib)')\n", + "total_water_date" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ORIGINAL\n", + "\n", + "session_with_date = behavior.TrialSet.proj('n_trials') \\\n", + " * (acquisition.Session.proj(session_date='DATE(session_start_time)') & 'session_date > \"2019-05-01\"')" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

subject_uuid

\n", + " \n", + "
\n", + "

session_start_time

\n", + " start time\n", + "
\n", + "

n_trials

\n", + " total trial numbers in this set\n", + "
\n", + "

session_date

\n", + " calculated attribute\n", + "
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-02 20:56:224862019-04-02
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-03 20:46:099962019-04-03
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-04 19:55:124282019-04-04
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-04 20:33:462622019-04-04
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-05 16:00:217862019-04-05
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-08 23:19:007722019-04-08
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-09 19:42:56592019-04-09
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-09 19:48:299282019-04-09
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-04-10 10:37:3610032019-04-10
02120449-9b19-4276-a434-513886c2fb192019-04-02 21:06:189582019-04-02
02120449-9b19-4276-a434-513886c2fb192019-04-03 20:50:119342019-04-03
02120449-9b19-4276-a434-513886c2fb192019-04-04 19:52:126442019-04-04
\n", + "

...

\n", + "

Total: 327

\n", + " " + ], + "text/plain": [ + "*subject_uuid *session_start n_trials session_date \n", + "+------------+ +------------+ +----------+ +------------+\n", + "00c60db3-74c3- 2019-04-02 20: 486 2019-04-02 \n", + "00c60db3-74c3- 2019-04-03 20: 996 2019-04-03 \n", + "00c60db3-74c3- 2019-04-04 19: 428 2019-04-04 \n", + "00c60db3-74c3- 2019-04-04 20: 262 2019-04-04 \n", + "00c60db3-74c3- 2019-04-05 16: 786 2019-04-05 \n", + "00c60db3-74c3- 2019-04-08 23: 772 2019-04-08 \n", + "00c60db3-74c3- 2019-04-09 19: 59 2019-04-09 \n", + "00c60db3-74c3- 2019-04-09 19: 928 2019-04-09 \n", + "00c60db3-74c3- 2019-04-10 10: 1003 2019-04-10 \n", + "02120449-9b19- 2019-04-02 21: 958 2019-04-02 \n", + "02120449-9b19- 2019-04-03 20: 934 2019-04-03 \n", + "02120449-9b19- 2019-04-04 19: 644 2019-04-04 \n", + " ...\n", + " (Total: 327)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# IMPROVED\n", + "\n", + "session_date = behavior.TrialSet.proj(\n", + " 'n_trials', session_date='DATE(session_start_time)') & 'session_date > \"2019-04-01\"'\n", + "session_date" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# ORIGINAL\n", + "\n", + "# Now you can join (*) the two tables avg_weight_date and session_with_date.\n", + "# Join * will automatically find matched session_date in both tables, and only show entries where\n", + "# these dates exist in both tables. Note there are fewer entries in this resulting table, because\n", + "# on some dates weight is missing and other dates session is missing\n", + "b = total_water_date.aggr(avg_weight_date, keep_all_rows=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

subject_uuid

\n", + " \n", + "
\n", + "

session_date

\n", + " calculated attribute\n", + "
\n", + "

n

\n", + " calculated attribute\n", + "
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-02-191
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-02-211
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-061
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-071
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-081
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-091
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-111
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-121
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-131
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-141
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-151
00c60db3-74c3-4ee2-9df9-2c84acf84e922019-03-181
\n", + "

...

\n", + "

Total: 6421

\n", + " " + ], + "text/plain": [ + "*subject_uuid *session_date n \n", + "+------------+ +------------+ +---+\n", + "00c60db3-74c3- 2019-02-19 1 \n", + "00c60db3-74c3- 2019-02-21 1 \n", + "00c60db3-74c3- 2019-03-06 1 \n", + "00c60db3-74c3- 2019-03-07 1 \n", + "00c60db3-74c3- 2019-03-08 1 \n", + "00c60db3-74c3- 2019-03-09 1 \n", + "00c60db3-74c3- 2019-03-11 1 \n", + "00c60db3-74c3- 2019-03-12 1 \n", + "00c60db3-74c3- 2019-03-13 1 \n", + "00c60db3-74c3- 2019-03-14 1 \n", + "00c60db3-74c3- 2019-03-15 1 \n", + "00c60db3-74c3- 2019-03-18 1 \n", + " ...\n", + " (Total: 6421)" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# IMPROVED\n", + "b = total_water_date.aggr(avg_weight_date, n=\"count('*')\", keep_all_rows=True)\n", + "b" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From fcbac21e0188acb97823c23b3c81d4547b8cf2bc Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Tue, 14 May 2019 11:05:40 -0500 Subject: [PATCH 03/11] cosmetic improvement of Improvements.ipynb --- notebooks/Improvements.ipynb | 83 +++++++++++++++++------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/notebooks/Improvements.ipynb b/notebooks/Improvements.ipynb index bd442eb..f39470b 100644 --- a/notebooks/Improvements.ipynb +++ b/notebooks/Improvements.ipynb @@ -1,17 +1,15 @@ { "cells": [ { - "cell_type": "code", - "execution_count": 1, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# This notebook demonstrates some improvements of queries from the IBL notebook" + "## Some improvements of queries from an IBL query notebook" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [ { @@ -33,23 +31,22 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# ORIGINAL: \n", - "\n", + "### ORIGINAL: \n", + "```python\n", "# FIND THE DATA WE NEED\n", "# FIRST, WHICH SUBJECTS ARE DOING THIS CA EXPERIMENT?\n", "subj = (subject.Subject() - subject.Death & 'subject_birth_date < \"2018-09-01\"').proj('subject_nickname', 'sex') * \\\n", " (subject.SubjectLab() & 'lab_name=\"churchlandlab\"').proj()\n", - "print(subj)" + "print(subj)\n", + "```" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -168,7 +165,7 @@ " (Total: 15)" ] }, - "execution_count": 3, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -181,13 +178,12 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# ORIGINAL \n", + "### ORIGINAL \n", "\n", + "```python\n", "# get date for each weighing\n", "weight_with_date = action.Weighing.proj('weight', session_date='DATE(weighing_time)')\n", "# create a table with primary key to be the combination of subject_uuid and session_date\n", @@ -205,12 +201,13 @@ "# first argument is the table that is useful to compute the value you need, here weight_with_date\n", "# provides all weights for each date, 'weight' is an attribute in the table weight_with_date\n", "# note that the results have the same number of entries as weight_date\n", - "avg_weight_date = weight_date.aggr(weight_with_date, avg_weight='AVG(weight)')" + "avg_weight_date = weight_date.aggr(weight_with_date, avg_weight='AVG(weight)')\n", + "```" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -329,7 +326,7 @@ " (Total: 7898)" ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -343,25 +340,25 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# ORIGINAL\n", + "### ORIGINAL\n", "\n", + "```python\n", "# NOW DO THE SAME FOR WATER\n", "water_with_date = action.WaterAdministration.proj('watertype_name', 'water_administered', 'adlib', \n", " session_date='DATE(administration_time)')\n", "water_date = (dj.U('subject_uuid', 'session_date') & water_with_date)\n", "total_water_date = water_date.aggr(water_with_date, total_water='SUM(water_administered)', \n", " watertype=\"GROUP_CONCAT(DISTINCT watertype_name SEPARATOR '; ')\", \n", - " adlib='MAX(adlib)')\n" + " adlib='MAX(adlib)')\n", + "```" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -510,7 +507,7 @@ " (Total: 6421)" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -529,20 +526,19 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# ORIGINAL\n", - "\n", + "### ORIGINAL\n", + "```python\n", "session_with_date = behavior.TrialSet.proj('n_trials') \\\n", - " * (acquisition.Session.proj(session_date='DATE(session_start_time)') & 'session_date > \"2019-05-01\"')" + " * (acquisition.Session.proj(session_date='DATE(session_start_time)') & 'session_date > \"2019-05-01\"')\n", + "```" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -676,7 +672,7 @@ " (Total: 327)" ] }, - "execution_count": 11, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -690,23 +686,22 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# ORIGINAL\n", - "\n", + "### ORIGINAL\n", + "```python\n", "# Now you can join (*) the two tables avg_weight_date and session_with_date.\n", "# Join * will automatically find matched session_date in both tables, and only show entries where\n", "# these dates exist in both tables. Note there are fewer entries in this resulting table, because\n", "# on some dates weight is missing and other dates session is missing\n", - "b = total_water_date.aggr(avg_weight_date, keep_all_rows=True)" + "b = total_water_date.aggr(avg_weight_date, keep_all_rows=True)\n", + "```" ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -825,14 +820,14 @@ " (Total: 6421)" ] }, - "execution_count": 13, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# IMPROVED\n", - "b = total_water_date.aggr(avg_weight_date, n=\"count('*')\", keep_all_rows=True)\n", + "b = total_water_date.aggr(avg_weight_date, n=\"count(*)\", keep_all_rows=True)\n", "b" ] }, From f136342e6b9a115d71e7659c789c1ce59a934072 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Thu, 30 May 2019 13:38:03 -0500 Subject: [PATCH 04/11] add Questions 1 and --- notebooks/Question-001.ipynb | 658 +++++++++++++++++++++++++++++++++++ notebooks/Question-002.ipynb | 615 ++++++++++++++++++++++++++++++++ 2 files changed, 1273 insertions(+) create mode 100644 notebooks/Question-001.ipynb create mode 100644 notebooks/Question-002.ipynb diff --git a/notebooks/Question-001.ipynb b/notebooks/Question-001.ipynb new file mode 100644 index 0000000..84095c5 --- /dev/null +++ b/notebooks/Question-001.ipynb @@ -0,0 +1,658 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# User Question 001\n", + "\n", + "A new user asks:\n", + "> Suppose, for example, that there were two experimenters who worked together to collect data for a given session. I understand how to create an Experimenter table and how to make a Session table that includes one experimenter, but I don’t understand how one might indicate that there were multiple experimenters for a given session.\n", + "\n", + "Okay, let's define a minimal example that answers this question.\n", + "\n", + "First, let's create a new database schema:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dimitri@localhost:3306\n" + ] + } + ], + "source": [ + "import datajoint as dj\n", + "schema = dj.schema('test_question001')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, let's define the `User` set to contain all the lab members who will conduct experiments and we will populate it with a few names." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class User(dj.Manual):\n", + " definition = \"\"\"\n", + " username : varchar(20)\n", + " ---\n", + " full_name='' : varchar(60) \n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# these are just fake names\n", + "User.insert([\n", + " ('ali', 'Ali Cameron'),\n", + " ('david', 'David Petry'),\n", + " ('pat', 'Patricia Avery')\n", + "])" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "
\n", + "

username

\n", + " \n", + "
\n", + "

full_name

\n", + " \n", + "
aliAli Cameron
davidDavid Petry
patPatricia Avery
\n", + " \n", + "

Total: 3

\n", + " " + ], + "text/plain": [ + "*username full_name \n", + "+----------+ +------------+\n", + "ali Ali Cameron \n", + "david David Petry \n", + "pat Patricia Avery\n", + " (Total: 3)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "User()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's define the `Session` set. Since there may be mulitple experimenters, we will not put the experimenter in the session. Rather, we will create a separate `Experimenter` set. " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Session(dj.Manual):\n", + " definition = \"\"\"\n", + " # Experiment session\n", + " session : int # session number\n", + " ---\n", + " session_date : date \n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Experimenter(dj.Manual):\n", + " definition = \"\"\"\n", + " # Persons performing experiments in the session\n", + " -> Session\n", + " -> User\n", + " \"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that both `Session` and `User` are in the primary key of `Experimenter`. This means that multiple users can be experimenters in each session. \n", + "\n", + "Let's add some sessions and experimenters that conducted them:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "Session.insert((\n", + " [1, '2018-04-09'],\n", + " [2, '2019-02-07'],\n", + " [3, '2019-03-31']\n", + "))\n", + "\n", + "Experimenter.insert([\n", + " (1, 'pat'),\n", + " (1, 'ali'),\n", + " (2, 'pat'),\n", + " (3, 'pat'),\n", + " (3, 'david') \n", + "])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We are done! Here is our new schema:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "\n", + "User\n", + "\n", + "\n", + "User\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Experimenter\n", + "\n", + "\n", + "Experimenter\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "User->Experimenter\n", + "\n", + "\n", + "\n", + "\n", + "Session\n", + "\n", + "\n", + "Session\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Session->Experimenter\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.Diagram(schema)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's try some queries: " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " Experiment session\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "
\n", + "

session

\n", + " session number\n", + "
\n", + "

session_date

\n", + " \n", + "
12018-04-09
22019-02-07
32019-03-31
\n", + " \n", + "

Total: 3

\n", + " " + ], + "text/plain": [ + "*session session_date \n", + "+---------+ +------------+\n", + "1 2018-04-09 \n", + "2 2019-02-07 \n", + "3 2019-03-31 \n", + " (Total: 3)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# All sessions\n", + "Session()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

session

\n", + " session number\n", + "
\n", + "

username

\n", + " \n", + "
\n", + "

session_date

\n", + " \n", + "
\n", + "

full_name

\n", + " \n", + "
1ali2018-04-09Ali Cameron
3david2019-03-31David Petry
1pat2018-04-09Patricia Avery
2pat2019-02-07Patricia Avery
3pat2019-03-31Patricia Avery
\n", + " \n", + "

Total: 5

\n", + " " + ], + "text/plain": [ + "*session *username session_date full_name \n", + "+---------+ +----------+ +------------+ +------------+\n", + "1 ali 2018-04-09 Ali Cameron \n", + "3 david 2019-03-31 David Petry \n", + "1 pat 2018-04-09 Patricia Avery\n", + "2 pat 2019-02-07 Patricia Avery\n", + "3 pat 2019-03-31 Patricia Avery\n", + " (Total: 5)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# All Session x Experimenter combinations\n", + "Session * Experimenter * User" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " Experiment session\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "
\n", + "

session

\n", + " session number\n", + "
\n", + "

session_date

\n", + " \n", + "
12018-04-09
\n", + " \n", + "

Total: 1

\n", + " " + ], + "text/plain": [ + "*session session_date \n", + "+---------+ +------------+\n", + "1 2018-04-09 \n", + " (Total: 1)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# All Sessions conducted by Ali\n", + "Session & (Experimenter & {'username': 'ali'})" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Question-002.ipynb b/notebooks/Question-002.ipynb new file mode 100644 index 0000000..36f7a00 --- /dev/null +++ b/notebooks/Question-002.ipynb @@ -0,0 +1,615 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# User Question 002\n", + "\n", + "A new user asks:\n", + "> We have the notion of a list of electrodes, which would fit nicely into an Electrode table, but then data are taken from groups of electrodes at a time (e.g. a tetrode, a 32 channel shank of a polymer probe, etc). Neurodata Without Borders (nwb.org) handles that with a table that indicates, for every data object, which electrodes were included. How are these sorts of references possible in DataJoint? \n", + "\n", + "Similar designs have been deployed by many DataJoint-based ephys schemas. \n", + "For example, here is on from the International Brain Lab https://github.com/int-brain-lab/IBL-pipeline/blob/master/ibl_pipeline/ephys.py\n", + "and another from the Mesoscale Activity Project https://github.com/mesoscale-activity-map/map-ephys/blob/master/pipeline/ephys.py\n", + "These schemas were designed to closely match NWB conventions and names.\n", + "\n", + "Let's define a minimal example:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, let's work with an existing schema defining experiment sessions and we will add ephys probes in our new schema within this notebook. \n", + "\n", + "Imagine that the schema designed in [User Question 001](Question-001.ipynb) can is defined in a module called `experiment.py`. Then we would be able to import it as \n", + "\n", + "```python\n", + "import experiment\n", + "```\n", + "\n", + "and access all its tables.\n", + "\n", + "However, that schema was defined in a notebook. DataJoint provides a method for importing a virtual module. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "import datajoint as dj\n", + "experiment = dj.create_virtual_module('experiment', 'test_question001')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can view the schema from [User Question 1](Question-001.ipynb), and access any of its data:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, let's define the `User` set to contain all the lab members who will conduct experiments and we will populate it with a few names." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "\n", + "experiment.User\n", + "\n", + "\n", + "experiment.User\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "experiment.Experimenter\n", + "\n", + "\n", + "experiment.Experimenter\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "experiment.User->experiment.Experimenter\n", + "\n", + "\n", + "\n", + "\n", + "experiment.Session\n", + "\n", + "\n", + "experiment.Session\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "experiment.Session->experiment.Experimenter\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.Diagram(experiment)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " Experiment session\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "
\n", + "

session

\n", + " session number\n", + "
\n", + "

session_date

\n", + " \n", + "
12018-04-09
22019-02-07
32019-03-31
\n", + " \n", + "

Total: 3

\n", + " " + ], + "text/plain": [ + "*session session_date \n", + "+---------+ +------------+\n", + "1 2018-04-09 \n", + "2 2019-02-07 \n", + "3 2019-03-31 \n", + " (Total: 3)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "experiment.Session()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's define a new schema for working with electrophysiology probes for the experiment session." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "schema = dj.schema('test_question002')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's define the `Probe` set to define various available probes. We choose to define as a lookup table, meaning that its contents is fairly static and is populated from the `contents` property of its class." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Probe(dj.Lookup):\n", + " definition = \"\"\"\n", + " # Ephys probe\n", + " probe_part_no : varchar(20)\n", + " ---\n", + " probe_type : varchar(32)\n", + " probe_comment : varchar(4000)\n", + " \"\"\"\n", + " contents = [\n", + " ('15131808323', 'neuropixels probe O3', ''),\n", + " ('H-194', 'janelia2x32', '')\n", + " ]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's define the `ElectrodeGroup` for a given session. These are electrodes on a probe. Multiple groups can be used in a single session. Hence, we add the `electrode_group` attribute to the primary key. We add `Probe` as a secondary attribute. We then add the `Electrode` set as a [part table](https://docs.datajoint.io/python/computation/03-master-part.html) of `ElectrodeGroup`." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class ElectrodeGroup(dj.Manual):\n", + " definition = \"\"\"\n", + " # Electrode\n", + " -> experiment.Session\n", + " electrode_group : tinyint # Electrode_group is like the probe\n", + " ---\n", + " -> Probe\n", + " \"\"\"\n", + "\n", + " class Electrode(dj.Part):\n", + " definition = \"\"\"\n", + " -> master\n", + " electrode : smallint # sites on the electrode\n", + " \"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is the entire pipeline with both schemas:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "\n", + "Probe\n", + "\n", + "\n", + "Probe\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ElectrodeGroup\n", + "\n", + "\n", + "ElectrodeGroup\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Probe->ElectrodeGroup\n", + "\n", + "\n", + "\n", + "\n", + "ElectrodeGroup.Electrode\n", + "\n", + "\n", + "ElectrodeGroup.Electrode\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ElectrodeGroup->ElectrodeGroup.Electrode\n", + "\n", + "\n", + "\n", + "\n", + "experiment.Experimenter\n", + "\n", + "\n", + "experiment.Experimenter\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "experiment.Session\n", + "\n", + "\n", + "experiment.Session\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "experiment.Session->ElectrodeGroup\n", + "\n", + "\n", + "\n", + "\n", + "experiment.Session->experiment.Experimenter\n", + "\n", + "\n", + "\n", + "\n", + "experiment.User\n", + "\n", + "\n", + "experiment.User\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "experiment.User->experiment.Experimenter\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.Diagram(schema) + dj.Diagram(experiment)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's populate an electrode group for Session 1 with 32 electrodes" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "key = dict(session=2, electrode_group=1)\n", + "ElectrodeGroup.insert1(dict(key, probe_part_no='H-194'))\n", + "ElectrodeGroup.Electrode.insert(dict(key, electrode=i) for i in range(32))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here is the result:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

session

\n", + " session number\n", + "
\n", + "

electrode_group

\n", + " Electrode_group is like the probe\n", + "
\n", + "

electrode

\n", + " sites on the electrode\n", + "
\n", + "

probe_part_no

\n", + " \n", + "
210H-194
211H-194
212H-194
213H-194
214H-194
215H-194
216H-194
\n", + "

...

\n", + "

Total: 32

\n", + " " + ], + "text/plain": [ + "*session *electrode_gro *electrode probe_part_no \n", + "+---------+ +------------+ +-----------+ +------------+\n", + "2 1 0 H-194 \n", + "2 1 1 H-194 \n", + "2 1 2 H-194 \n", + "2 1 3 H-194 \n", + "2 1 4 H-194 \n", + "2 1 5 H-194 \n", + "2 1 6 H-194 \n", + " ...\n", + " (Total: 32)" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ElectrodeGroup * ElectrodeGroup.Electrode & key" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Have fun with DataJoint!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From d56a6b8c9d81ffa2fc5d5f29b218ff73e326d355 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Fri, 19 Jul 2019 09:42:15 -0500 Subject: [PATCH 05/11] add ExternalMigration to demonstate how to migrate external blobs from 0.11 to 0.12 --- notebooks/External-Migration.ipynb | 942 +++++++++++++++++++++++++++++ 1 file changed, 942 insertions(+) create mode 100644 notebooks/External-Migration.ipynb diff --git a/notebooks/External-Migration.ipynb b/notebooks/External-Migration.ipynb new file mode 100644 index 0000000..032b5e2 --- /dev/null +++ b/notebooks/External-Migration.ipynb @@ -0,0 +1,942 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Migration of External Storage from DataJoint 0.11.* to 0.12.*\n", + "DataJoint 0.12 improves the efficiency of blob storage and expands its capabilities. Unfortunately, this breaks backward compatibility for external storage used in previous versions. This notebook describes the migration procedure from a 0.11 external store.\n", + "\n", + "First, let's emulate an legacy table with external storage. You do not need to perform these steps if you are migrating an existing database. I `git`-cloned `datajoint-python` as a subfolder in the datajoint folder, checked out the legacy version `v0.11.1`, and renamed the subfolder into `dj011`. This allows me to import the legacy version of datajoint while keeping the current version available as well:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import dj011 as dj # legacy version of datajoint" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0.11.1'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "dj.config['database.password'] = 'datajoint'\n", + "dj.config['database.user'] = 'datajoint'\n", + "dj.config['database.host'] = 'localhost'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting datajoint@localhost:3306\n", + "Proceed to delete entire schema `djtest_blobs`? [yes, No]: yes\n" + ] + } + ], + "source": [ + "schema = dj.schema('djtest_blobs')\n", + "schema.drop()\n", + "schema = dj.schema('djtest_blobs')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Configure stores\n", + "import os \n", + "\n", + "dj.config['external'] = dict(\n", + " protocol='s3',\n", + " endpoint=\"localhost:9000\",\n", + " bucket='migrate-test',\n", + " location='store',\n", + " access_key=\"datajoint\",\n", + " secret_key=\"datajoint\")\n", + "\n", + "dj.config['external-shared'] = dict(\n", + " protocol='s3',\n", + " endpoint=\"localhost:9000\",\n", + " bucket='migrate-test',\n", + " location='maps',\n", + " access_key=\"datajoint\",\n", + " secret_key=\"datajoint\")\n", + "\n", + "dj.config['external-local'] = dict(\n", + " protocol='file',\n", + " location=os.path.expanduser('~/temp/migrate-test'),\n", + " access_key=\"datajoint\",\n", + " secret_key=\"datajoint\")\n", + "\n", + "\n", + "dj.config['cache'] = os.path.expanduser('~/temp/dj-cache')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's define the legacy-style table with external blobs:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class A(dj.Manual):\n", + " definition = \"\"\"\n", + " id : int \n", + " ---\n", + " blob_external : external # uses S3\n", + " blob_share : external-shared # uses S3\n", + " \"\"\"\n", + "\n", + "@schema\n", + "class B(dj.Manual):\n", + " definition = \"\"\"\n", + " id : int \n", + " ---\n", + " blob_local : external-local # uses files\n", + " blob_share : external-shared # uses S3\n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "A.insert((\n", + " (0, np.random.randn(2,3,4), np.random.randn(3)),\n", + " (1, np.array([1,2,3]), np.array([1,2]))\n", + "))\n", + "\n", + "B.insert((\n", + " (0, np.random.randn(2,3,4), np.random.randn(3)),\n", + " (1, np.array([1,2,3]), np.array([1,2]))\n", + "))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Upgrade legacy blobs\n", + "(restart kernel)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import datajoint as dj" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0.12.dev4'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "dj.config['database.password'] = 'datajoint'\n", + "dj.config['database.user'] = 'datajoint'\n", + "dj.config['database.host'] = 'localhost'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting datajoint@localhost:3306\n" + ] + } + ], + "source": [ + "schema = dj.schema('djtest_blobs')\n", + "query = schema.connection.query" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Configure stores\n", + "import os \n", + "\n", + "default_store = 'external' # naming the unnamed external store\n", + "\n", + "dj.config['stores'] = {\n", + " \n", + " default_store: dict(\n", + " protocol='s3',\n", + " endpoint=\"localhost:9000\",\n", + " bucket='migrate-test',\n", + " location='store',\n", + " access_key=\"datajoint\",\n", + " secret_key=\"datajoint\"),\n", + " \n", + " 'shared': dict(\n", + " protocol='s3',\n", + " endpoint=\"localhost:9000\",\n", + " bucket='migrate-test',\n", + " location='maps',\n", + " access_key=\"datajoint\",\n", + " secret_key=\"datajoint\"),\n", + " \n", + " 'local': dict(\n", + " protocol='file',\n", + " location=os.path.expanduser('~/temp/migrate-test'))\n", + "}\n", + "\n", + "dj.config['cache'] = os.path.expanduser('~/temp/dj-cache')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class C(dj.Manual):\n", + " definition = \"\"\"\n", + " id : int\n", + " ---\n", + " blo : blob@shared # just a check\n", + " \"\"\"\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "id : int \n", + "---\n", + "blo : blob@shared # just a check\n", + "INDEX (blo)\n", + "\n" + ] + } + ], + "source": [ + "C.describe();" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "schema.spawn_missing_classes()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "ename": "DataJointError", + "evalue": "Legacy datatype `external`.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mDataJointError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/.local/lib/python3.6/site-packages/IPython/core/formatters.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, obj)\u001b[0m\n\u001b[1;32m 700\u001b[0m \u001b[0mtype_pprinters\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtype_printers\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 701\u001b[0m deferred_pprinters=self.deferred_printers)\n\u001b[0;32m--> 702\u001b[0;31m \u001b[0mprinter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpretty\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 703\u001b[0m \u001b[0mprinter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mflush\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 704\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mstream\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetvalue\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[0;32m~/.local/lib/python3.6/site-packages/IPython/lib/pretty.py\u001b[0m in \u001b[0;36mpretty\u001b[0;34m(self, obj)\u001b[0m\n\u001b[1;32m 400\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcls\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mobject\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mcallable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__dict__\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'__repr__'\u001b[0m\u001b[0;34m)\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[0;32m--> 402\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_repr_pprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcycle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 403\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 404\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0m_default_pprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcycle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/.local/lib/python3.6/site-packages/IPython/lib/pretty.py\u001b[0m in \u001b[0;36m_repr_pprint\u001b[0;34m(obj, p, cycle)\u001b[0m\n\u001b[1;32m 695\u001b[0m \u001b[0;34m\"\"\"A pprint that just redirects to the normal repr function.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 696\u001b[0m \u001b[0;31m# Find newlines and replace them with p.break_()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 697\u001b[0;31m \u001b[0moutput\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrepr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 698\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0midx\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0moutput_line\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moutput\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplitlines\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\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 699\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0midx\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/datajoint-python/datajoint/expression.py\u001b[0m in \u001b[0;36m__repr__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 393\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 394\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__repr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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[0;32m--> 395\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__repr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'loglevel'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlower\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'debug'\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpreview\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[0m\u001b[1;32m 396\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 397\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mpreview\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlimit\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwidth\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\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[0;32m~/dev/datajoint-python/datajoint/expression.py\u001b[0m in \u001b[0;36mpreview\u001b[0;34m(self, limit, width)\u001b[0m\n\u001b[1;32m 399\u001b[0m \u001b[0mreturns\u001b[0m \u001b[0ma\u001b[0m \u001b[0mpreview\u001b[0m \u001b[0mof\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mcontents\u001b[0m \u001b[0mof\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mquery\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 400\u001b[0m \"\"\"\n\u001b[0;32m--> 401\u001b[0;31m \u001b[0mheading\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mheading\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 402\u001b[0m \u001b[0mrel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mproj\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mheading\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnon_blobs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 403\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlimit\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/datajoint-python/datajoint/table.py\u001b[0m in \u001b[0;36mheading\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 52\u001b[0m 'Missing schema decorator on the class? (e.g. @schema)')\n\u001b[1;32m 53\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 54\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_heading\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minit_from_database\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdatabase\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtable_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 55\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_heading\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 56\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/datajoint-python/datajoint/heading.py\u001b[0m in \u001b[0;36minit_from_database\u001b[0;34m(self, conn, database, table_name)\u001b[0m\n\u001b[1;32m 227\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 228\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mattr\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstartswith\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'external'\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[0;32m--> 229\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Legacy datatype `{type}`.'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 230\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Unknown attribute type `{type}`'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 231\u001b[0m attr.update(\n", + "\u001b[0;31mDataJointError\u001b[0m: Legacy datatype `external`." + ] + }, + { + "ename": "DataJointError", + "evalue": "Legacy datatype `external`.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mDataJointError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/.local/lib/python3.6/site-packages/IPython/core/formatters.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, obj)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_real_method\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprint_method\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mmethod\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[0m\u001b[1;32m 346\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/datajoint-python/datajoint/expression.py\u001b[0m in \u001b[0;36m_repr_html_\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 421\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 422\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_repr_html_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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[0;32m--> 423\u001b[0;31m \u001b[0mheading\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mheading\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 424\u001b[0m \u001b[0mrel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mproj\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mheading\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnon_blobs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 425\u001b[0m \u001b[0minfo\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mheading\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtable_info\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/datajoint-python/datajoint/table.py\u001b[0m in \u001b[0;36mheading\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 52\u001b[0m 'Missing schema decorator on the class? (e.g. @schema)')\n\u001b[1;32m 53\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 54\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_heading\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minit_from_database\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdatabase\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtable_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 55\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_heading\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 56\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/datajoint-python/datajoint/heading.py\u001b[0m in \u001b[0;36minit_from_database\u001b[0;34m(self, conn, database, table_name)\u001b[0m\n\u001b[1;32m 227\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 228\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mattr\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstartswith\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'external'\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[0;32m--> 229\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Legacy datatype `{type}`.'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 230\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Unknown attribute type `{type}`'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 231\u001b[0m attr.update(\n", + "\u001b[0;31mDataJointError\u001b[0m: Legacy datatype `external`." + ] + } + ], + "source": [ + "A()" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "LEGACY_HASH_SIZE = 43\n", + "\n", + "legacy_external = dj.FreeTable(\n", + " schema.connection,\n", + " '`{db}`.`~external`'.format(db=schema.database))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " the hash of stored object + store name\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
AbOdLZWSNmvYrfESJci85yLPplWIUM9E7UmyzHg0ApM2372019-07-19 13:22:54
BEq9eh9LlqkPOKS8PwbqsOX3PTom0MhLmqvlN43yfrsshared532019-07-19 13:22:54
FoRROa2LWM6_wx0RIQ0J-LVvgm256cqDQfJa066HoTEshared372019-07-19 13:22:54
l3MDivFfPe1GV74Fdyky4YSLVKq3Y4x_U7mtzAReSaUlocal2372019-07-19 13:22:54
U7u2I13bb6Zx2bC7yn_J8yCYos6fDebQBJhaUf4ho2Eshared532019-07-19 13:22:54
_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94402019-07-19 13:22:54
_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94local402019-07-19 13:22:54
\n", + " \n", + "

Total: 7

\n", + " " + ], + "text/plain": [ + "FreeTable(`djtest_blobs`.`~external`)" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "legacy_external" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# get referencing tables\n", + "refs = query(\"\"\"\n", + "SELECT concat('`', table_schema, '`.`', table_name, '`') as referencing_table, column_name, constraint_name\n", + "FROM information_schema.key_column_usage\n", + "WHERE referenced_table_name=\"{tab}\" and referenced_table_schema=\"{db}\"\n", + "\"\"\".format(tab=legacy_external.table_name, db=legacy_external.database), as_dict=True).fetchall()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "import re\n", + "\n", + "for ref in refs:\n", + " # get comment\n", + " column = query(\n", + " 'SHOW FULL COLUMNS FROM {referencing_table}'\n", + " 'WHERE Field=\"{column_name}\"'.format(**ref), as_dict=True).fetchone()\n", + "\n", + " store, comment = re.match(\n", + " r':external(-(?P.+))?:(?P.*)', \n", + " column['Comment']).group('store', 'comment')\n", + "\n", + " # get all the hashes from the reference\n", + " hashes = {x[0] for x in query(\n", + " 'SELECT `{column_name}` FROM {referencing_table}'.format(**ref))}\n", + "\n", + " # sanity check make sure that store suffixes match\n", + " if store is None:\n", + " assert all(len(_) == LEGACY_HASH_SIZE for _ in hashes)\n", + " else:\n", + " assert all(_[LEGACY_HASH_SIZE:] == store for _ in hashes)\n", + "\n", + " # create new-style external table\n", + " ext = schema.external[store or default_store]\n", + "\n", + " # add the new-style reference field\n", + " temp_suffix = 'tempsub'\n", + "\n", + " try:\n", + " query(\"\"\"ALTER TABLE {referencing_table} \n", + " ADD COLUMN `{column_name}_{temp_suffix}` {type} DEFAULT NULL\n", + " COMMENT \":blob@{store}:{comment}\"\n", + " \"\"\".format(type=dj.declare.UUID_DATA_TYPE, \n", + " temp_suffix=temp_suffix, \n", + " store=(store or default_store), comment=comment, **ref))\n", + " except:\n", + " print('Column already added')\n", + " pass\n", + "\n", + "\n", + " # Copy references into the new external table\n", + " # No Windows! Backslashes will cause problems\n", + "\n", + " contents_hash_function = {\n", + " 'file': lambda ext, relative_path: dj.hash.uuid_from_file(os.path.join(ext.spec['location'], relative_path)),\n", + " 's3': lambda ext, relative_path: dj.hash.uuid_from_buffer(ext.s3.get(relative_path))\n", + " }\n", + "\n", + " for _hash, size in zip(*legacy_external.fetch('hash', 'size')):\n", + " if _hash in hashes:\n", + " relative_path = os.path.join(schema.database, _hash)\n", + " uuid = dj.hash.uuid_from_buffer(init_string=relative_path)\n", + " ext.insert1(dict(\n", + " filepath=relative_path,\n", + " size=size,\n", + " contents_hash=contents_hash_function[ext.spec['protocol']](ext, relative_path),\n", + " hash=uuid\n", + " ), skip_duplicates=True)\n", + "\n", + " query('UPDATE {referencing_table} '\n", + " 'SET `{column_name}_{temp_suffix}`=%s '\n", + " 'WHERE `{column_name}` = \"{_hash}\"'\n", + " .format(_hash=_hash, temp_suffix=temp_suffix, **ref), uuid.bytes)\n", + "\n", + " # check that all have been copied\n", + " check = query('SELECT * FROM {referencing_table} '\n", + " 'WHERE `{column_name}` IS NOT NULL'\n", + " ' AND `{column_name}_{temp_suffix}` IS NULL'\n", + " .format(temp_suffix=temp_suffix, **ref)).fetchall()\n", + "\n", + " assert len(check) == 0, 'Some hashes havent been migrated'\n", + "\n", + " # drop old foreign key, rename, and create new foreign key\n", + " query(\"\"\"\n", + " ALTER TABLE {referencing_table}\n", + " DROP FOREIGN KEY `{constraint_name}`,\n", + " DROP COLUMN `{column_name}`,\n", + " CHANGE COLUMN `{column_name}_{temp_suffix}` `{column_name}` {type} DEFAULT NULL\n", + " COMMENT \":blob@{store}:{comment}\",\n", + " ADD FOREIGN KEY (`{column_name}`) REFERENCES {ext_table_name} (`hash`)\n", + " \"\"\".format(temp_suffix=temp_suffix, \n", + " ext_table_name=ext.full_table_name, \n", + " type=dj.declare.UUID_DATA_TYPE, \n", + " store=(store or default_store), comment=comment, **ref))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " the hash of stored object + store name\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
AbOdLZWSNmvYrfESJci85yLPplWIUM9E7UmyzHg0ApM2372019-07-19 13:22:54
BEq9eh9LlqkPOKS8PwbqsOX3PTom0MhLmqvlN43yfrsshared532019-07-19 13:22:54
FoRROa2LWM6_wx0RIQ0J-LVvgm256cqDQfJa066HoTEshared372019-07-19 13:22:54
l3MDivFfPe1GV74Fdyky4YSLVKq3Y4x_U7mtzAReSaUlocal2372019-07-19 13:22:54
U7u2I13bb6Zx2bC7yn_J8yCYos6fDebQBJhaUf4ho2Eshared532019-07-19 13:22:54
_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94402019-07-19 13:22:54
_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94local402019-07-19 13:22:54
\n", + " \n", + "

Total: 7

\n", + " " + ], + "text/plain": [ + "FreeTable(`djtest_blobs`.`~external`)" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "legacy_external" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "# Drop the old external table but make sure it's no longer referenced\n", + "# get referencing tables\n", + "refs = query(\"\"\"\n", + "SELECT concat('`', table_schema, '`.`', table_name, '`') as referencing_table, column_name, constraint_name\n", + "FROM information_schema.key_column_usage\n", + "WHERE referenced_table_name=\"{tab}\" and referenced_table_schema=\"{db}\"\n", + "\"\"\".format(tab=legacy_external.table_name, db=legacy_external.database), as_dict=True).fetchall()\n", + "\n", + "assert not refs, 'Some references still exist'" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# drop old external table\n", + "legacy_external.drop_quick()" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

filepath

\n", + " relative filepath used in the filepath datatype\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
83186db4-c969-0298-3ec8-1da403c715d540djtest_blobs/_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94069fe219-23b4-62e5-fbfe-da572fc47f7d2019-07-19 13:34:30
b052bba1-018d-ec41-3c35-33bb7df4cb90237NoneNone2019-07-19 13:41:29
d4b9b701-b577-d088-e6f7-135f060b9cfb237djtest_blobs/AbOdLZWSNmvYrfESJci85yLPplWIUM9E7UmyzHg0ApM69391462-c54e-1f19-2f78-7f3f2eccb9b92019-07-19 13:34:30
ea5894dc-3a46-5ebe-4bbd-e80ebf08b16153NoneNone2019-07-19 13:41:29
\n", + " \n", + "

Total: 4

\n", + " " + ], + "text/plain": [ + "*hash size filepath contents_hash timestamp \n", + "+------------+ +------+ +------------+ +------------+ +------------+\n", + "83186db4-c969- 40 djtest_blobs/_ 069fe219-23b4- 2019-07-19 13:\n", + "b052bba1-018d- 237 None None 2019-07-19 13:\n", + "d4b9b701-b577- 237 djtest_blobs/A 69391462-c54e- 2019-07-19 13:\n", + "ea5894dc-3a46- 53 None None 2019-07-19 13:\n", + " (Total: 4)" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['external']" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [], + "source": [ + "import datajoint as dj\n", + "\n", + "dj.config['database.password'] = 'datajoint'\n", + "dj.config['database.user'] = 'datajoint'\n", + "dj.config['database.host'] = 'localhost'\n", + "\n", + "schema = dj.schema('djtest_blobs')\n", + "query = schema.connection.query" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "schema.spawn_missing_classes()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dj.ERD(schema)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "A.insert((\n", + " (2, np.random.randn(2,3,4), np.random.randn(3)),\n", + " (3, np.array([1,2,3]), np.array([1,2]))\n", + "))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "A.fetch('blob_share')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "os.path.join('one', 'two', 'three\\\\four')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From cdae43433294c838f577aebe2a9210d0f4097047 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Tue, 6 Aug 2019 09:26:24 -0500 Subject: [PATCH 06/11] add AdaptedTypes.ipynb to demonstrate dj.AdaptedAttribute --- notebooks/Adapted-Types.ipynb | 397 ++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) create mode 100644 notebooks/Adapted-Types.ipynb diff --git a/notebooks/Adapted-Types.ipynb b/notebooks/Adapted-Types.ipynb new file mode 100644 index 0000000..0622ec2 --- /dev/null +++ b/notebooks/Adapted-Types.ipynb @@ -0,0 +1,397 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# User-defined Attribute Types\n", + "\n", + "**Purpose**: demonstrate using `dj.AttributeAdapter` for convenient storage of arbitrary data types in DataJoint table attributes." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Imagine I want store graph objects of type `networkx.Graph` in the form of edge lists. \n", + "\n", + "First, let's create a few graphs:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "from matplotlib import pyplot as plt\n", + "import networkx as nx\n", + "graphs = [nx.lollipop_graph(4, 2), nx.star_graph(5), nx.barbell_graph(3, 1), nx.cycle_graph(5)]\n", + "\n", + "fig, axx = plt.subplots(1, len(graphs) , figsize=(15, 3))\n", + "for g, ax in zip(graphs, axx.flatten()):\n", + " plt.sca(ax)\n", + " nx.draw(g)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we need to define an adapter object that convert target objects into an attribute type that datajoint can already store. The class must subclass `dj.AttributeAdapter` and define the property `attribute_type`, and methods `get` " + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import datajoint as dj\n", + "\n", + "class GraphAdapter(dj.AttributeAdapter):\n", + " \n", + " attribute_type = 'longblob' # this is how the attribute will be declared\n", + " \n", + " def get(self, obj):\n", + " return nx.Graph(obj)\n", + " \n", + " def put(self, obj):\n", + " # convert graph object into an edgelist\n", + " assert isinstance(obj, nx.Graph)\n", + " return list(obj.edges)\n", + "\n", + "# instantiate for use as a datajoint type\n", + "graph = GraphAdapter()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can define a table that uses `graph` as its attribute type. These \"adapted types\" must be enclosed in angle brackets as in ``:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dimitri@localhost:3306\n" + ] + } + ], + "source": [ + "schema = dj.schema('test_graphs')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Connectivity(dj.Manual):\n", + " definition = \"\"\"\n", + " cid : int\n", + " ---\n", + " connectivity : # a networkx.Graph object \n", + " \"\"\"\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "Connectivity.insert((i, g) for i, g in enumerate(graphs))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

cid

\n", + " \n", + "
\n", + "

connectivity

\n", + " a networkx.Graph object\n", + "
0=BLOB=
1=BLOB=
2=BLOB=
3=BLOB=
\n", + " \n", + "

Total: 4

\n", + " " + ], + "text/plain": [ + "*cid connectivi\n", + "+-----+ +--------+\n", + "0 =BLOB= \n", + "1 =BLOB= \n", + "2 =BLOB= \n", + "3 =BLOB= \n", + " (Total: 4)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Connectivity()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "g = Connectivity.fetch('connectivity')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axx = plt.subplots(1, len(graphs) , figsize=(15, 3))\n", + "for g, ax in zip(graphs, axx.flatten()):\n", + " plt.sca(ax)\n", + " nx.draw(g)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As another example, let's pack a positive fraction as a single uint64 number" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "from fractions import Fraction" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Fraction(12, 7)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a = Fraction(3,7) / Fraction(2,8)\n", + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "7" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a.denominator" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class FractionAdapter(dj.AttributeAdapter):\n", + " \n", + " attribute_type = 'bigint unsigned'\n", + " \n", + " @staticmethod\n", + " def put(fraction):\n", + " assert isinstance(fraction, Fraction)\n", + " assert 0 <= fraction.denominator < (1 << 32)-1 \n", + " assert 0 <= fraction.numerator < (1 << 32)-1 \n", + " return (fraction.numerator << 32) + fraction.denominator\n", + " \n", + " @staticmethod\n", + " def get(uint64):\n", + " return Fraction(uint64 >> 32, uint64 % (1 << 32))\n", + " \n", + "frac = FractionAdapter()\n", + " \n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "@schema \n", + "class Frac(dj.Manual):\n", + " definition = \"\"\"\n", + " frac : \n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Frac.insert1([Fraction(1,3)])\n", + "Frac.insert1([Fraction(2,3)])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Frac.fetch(as_dict=True)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From f37d77c31ef73639b0ad52fe32452fd86cf9f4f5 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Wed, 7 Aug 2019 16:32:43 -0500 Subject: [PATCH 07/11] Update the notebooks for Adapted Types to show how to work with spawned classes --- notebooks/Adapted-Types-2.ipynb | 257 +++++++++++++++++++++++++++ notebooks/Adapted-Types.ipynb | 298 +++++++++----------------------- 2 files changed, 334 insertions(+), 221 deletions(-) create mode 100644 notebooks/Adapted-Types-2.ipynb diff --git a/notebooks/Adapted-Types-2.ipynb b/notebooks/Adapted-Types-2.ipynb new file mode 100644 index 0000000..7bc141b --- /dev/null +++ b/notebooks/Adapted-Types-2.ipynb @@ -0,0 +1,257 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Adapted Attribute Types with Spawned Classes and Virtual Modules\n", + "\n", + "**Purpose**: demonstrate using `dj.AttributeAdapter` for convenient storage of arbitrary data types in DataJoint table attributes when working with previously defined schemas.\n", + "\n", + "This notebook works with the schema created previously in [Adapted-Types.ipynb](Adapted-Types.ipynb). Please execute it first, leaving the `Connection` table defined and populated.\n", + "\n", + "Also, see [Spawning-Classes.ipynb](Spawning-Classes.ipynb) for a review of `schema.spawn_missing_classes` and `dj.create_virtual_module`. " + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import networkx as nx\n", + "import datajoint as dj" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's connect to the schema defined in [Adapted-Types.ipynb](Adapted-Types.ipynb)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dimitri@localhost:3306\n" + ] + } + ], + "source": [ + "schema = dj.schema('test_graphs')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To work with the `` type used in that schema we need to define or import the adapter object *before* `spawn_missing_classes`:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "class GraphAdapter(dj.AttributeAdapter):\n", + " \n", + " attribute_type = 'longblob' # this is how the attribute will be declared\n", + " \n", + " def put(self, obj):\n", + " # convert the nx.Graph object into an edge list\n", + " assert isinstance(obj, nx.Graph)\n", + " return list(obj.edges)\n", + "\n", + " def get(self, value):\n", + " # convert edge list back into an nx.Graph\n", + " return nx.Graph(value)\n", + " \n", + "\n", + "# instantiate for use as a datajoint type\n", + "graph = GraphAdapter()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Spawning missing classes in the local namespace" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now spawning missing classes will have the type adapter accessible:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "schema.spawn_missing_classes()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/dimitri/.local/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py:579: MatplotlibDeprecationWarning: \n", + "The iterable function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use np.iterable instead.\n", + " if not cb.iterable(width):\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "from matplotlib import pyplot as plt\n", + "\n", + "result = Connectivity.fetch('conn_graph', order_by='conn_id')\n", + "\n", + "fig, axx = plt.subplots(1, result.size , figsize=(15, 3))\n", + "for g, ax in zip(result, axx.flatten()):\n", + " plt.sca(ax)\n", + " nx.draw(g)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creating a virtual module with adapted attribute types\n", + "\n", + "To allow adapted attribyte types in virtual modules, they must be passed into the virtual module using the `add_objects` argument:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "vmod = dj.create_virtual_module('vmod', 'test_graphs', add_objects={'graph': graph})" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "\n", + "Connectivity\n", + "\n", + "\n", + "Connectivity\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.Diagram(vmod)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/dimitri/.local/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py:579: MatplotlibDeprecationWarning: \n", + "The iterable function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use np.iterable instead.\n", + " if not cb.iterable(width):\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "result = vmod.Connectivity.fetch('conn_graph', order_by='conn_id')\n", + "\n", + "fig, axx = plt.subplots(1, result.size , figsize=(15, 3))\n", + "for g, ax in zip(result, axx.flatten()):\n", + " plt.sca(ax)\n", + " nx.draw(g)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Adapted-Types.ipynb b/notebooks/Adapted-Types.ipynb index 0622ec2..fb8825a 100644 --- a/notebooks/Adapted-Types.ipynb +++ b/notebooks/Adapted-Types.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# User-defined Attribute Types\n", + "# Adapted Attribute Types\n", "\n", "**Purpose**: demonstrate using `dj.AttributeAdapter` for convenient storage of arbitrary data types in DataJoint table attributes." ] @@ -23,9 +23,18 @@ "execution_count": 1, "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/dimitri/.local/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py:579: MatplotlibDeprecationWarning: \n", + "The iterable function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use np.iterable instead.\n", + " if not cb.iterable(width):\n" + ] + }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -46,16 +55,25 @@ " nx.draw(g)" ] }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Then we need to define an adapter object that convert target objects into an attribute type that datajoint can already store. The class must subclass `dj.AttributeAdapter` and define the property `attribute_type`, and methods `get` " + "Then we need to define an adapter object that convert target objects into an attribute type that datajoint can already store. The class must subclass `dj.AttributeAdapter` and define the property `attribute_type`, and methods `get` and `put`. These methods translate the adapted data type `nx.Graph` into a representation that can be stored in datajoint, a `longblob` storing the edge list." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -65,14 +83,16 @@ " \n", " attribute_type = 'longblob' # this is how the attribute will be declared\n", " \n", - " def get(self, obj):\n", - " return nx.Graph(obj)\n", - " \n", " def put(self, obj):\n", - " # convert graph object into an edgelist\n", + " # convert the nx.Graph object into an edge list\n", " assert isinstance(obj, nx.Graph)\n", " return list(obj.edges)\n", "\n", + " def get(self, value):\n", + " # convert edge list back into an nx.Graph\n", + " return nx.Graph(value)\n", + " \n", + "\n", "# instantiate for use as a datajoint type\n", "graph = GraphAdapter()" ] @@ -86,44 +106,37 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Connecting dimitri@localhost:3306\n" + "Connecting dimitri@localhost:3306\n", + "Proceed to delete entire schema `test_graphs`? [yes, No]: yes\n" ] } ], "source": [ - "schema = dj.schema('test_graphs')" + "schema = dj.schema('test_graphs')\n", + "schema.drop() # drop previous contents\n", + "schema = dj.schema('test_graphs') # create de novo" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "@schema\n", "class Connectivity(dj.Manual):\n", " definition = \"\"\"\n", - " cid : int\n", + " conn_id : int\n", " ---\n", - " connectivity : # a networkx.Graph object \n", - " \"\"\"\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "Connectivity.insert((i, g) for i, g in enumerate(graphs))" + " conn_graph = null : # a networkx.Graph object \n", + " \"\"\"" ] }, { @@ -132,235 +145,78 @@ "metadata": {}, "outputs": [ { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "

cid

\n", - " \n", - "
\n", - "

connectivity

\n", - " a networkx.Graph object\n", - "
0=BLOB=
1=BLOB=
2=BLOB=
3=BLOB=
\n", - " \n", - "

Total: 4

\n", - " " - ], - "text/plain": [ - "*cid connectivi\n", - "+-----+ +--------+\n", - "0 =BLOB= \n", - "1 =BLOB= \n", - "2 =BLOB= \n", - "3 =BLOB= \n", - " (Total: 4)" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Connectivity()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "g = Connectivity.fetch('connectivity')" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "conn_id : int \n", + "---\n", + "conn_graph=null : # a networkx.Graph object\n", + "\n" + ] } ], "source": [ - "fig, axx = plt.subplots(1, len(graphs) , figsize=(15, 3))\n", - "for g, ax in zip(graphs, axx.flatten()):\n", - " plt.sca(ax)\n", - " nx.draw(g)" + "Connectivity.describe();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "As another example, let's pack a positive fraction as a single uint64 number" + "### Now, populate the table with our example graphs and fetch them as objects\n", + "Inserting the graphs as objects" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "from fractions import Fraction" + "Connectivity.insert((i, g) for i, g in enumerate(graphs))" ] }, { - "cell_type": "code", - "execution_count": 10, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Fraction(12, 7)" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "a = Fraction(3,7) / Fraction(2,8)\n", - "a" + "We can now fetch the graphs as an array of objects and plot them to verify successful recovery." ] }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, + "execution_count": 8, + "metadata": { + "scrolled": true + }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/dimitri/.local/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py:579: MatplotlibDeprecationWarning: \n", + "The iterable function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use np.iterable instead.\n", + " if not cb.iterable(width):\n" + ] + }, { "data": { + "image/png": "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\n", "text/plain": [ - "7" + "
" ] }, - "execution_count": 11, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ - "a.denominator" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class FractionAdapter(dj.AttributeAdapter):\n", - " \n", - " attribute_type = 'bigint unsigned'\n", - " \n", - " @staticmethod\n", - " def put(fraction):\n", - " assert isinstance(fraction, Fraction)\n", - " assert 0 <= fraction.denominator < (1 << 32)-1 \n", - " assert 0 <= fraction.numerator < (1 << 32)-1 \n", - " return (fraction.numerator << 32) + fraction.denominator\n", - " \n", - " @staticmethod\n", - " def get(uint64):\n", - " return Fraction(uint64 >> 32, uint64 % (1 << 32))\n", - " \n", - "frac = FractionAdapter()\n", - " \n", - " \n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "@schema \n", - "class Frac(dj.Manual):\n", - " definition = \"\"\"\n", - " frac : \n", - " \"\"\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Frac.insert1([Fraction(1,3)])\n", - "Frac.insert1([Fraction(2,3)])" + "result = Connectivity.fetch('conn_graph', order_by='conn_id')\n", + "\n", + "fig, axx = plt.subplots(1, result.size, figsize=(15, 3))\n", + "for g, ax in zip(result, axx.flatten()):\n", + " plt.sca(ax)\n", + " nx.draw(g)" ] }, { @@ -369,7 +225,7 @@ "metadata": {}, "outputs": [], "source": [ - "Frac.fetch(as_dict=True)" + "Connectivity.insert1()" ] } ], @@ -389,7 +245,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.3" } }, "nbformat": 4, From 9ac813b0c9651584908b19b9dde5d2d8e43ef0e9 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Sat, 10 Aug 2019 19:36:47 -0500 Subject: [PATCH 08/11] Add DataJoint Course 1. --- dj-course-01/000-Contents.ipynb | 104 ++ dj-course-01/010-Setup.ipynb | 71 ++ notebooks/Alter.ipynb | 2074 +++++++++++-------------------- notebooks/Filepaths.ipynb | 484 +++++++- notebooks/Improvements.ipynb | 608 ++++++++- notebooks/Question-002.ipynb | 2 +- notebooks/UUID.ipynb | 301 ++++- 7 files changed, 2165 insertions(+), 1479 deletions(-) create mode 100644 dj-course-01/000-Contents.ipynb create mode 100644 dj-course-01/010-Setup.ipynb diff --git a/dj-course-01/000-Contents.ipynb b/dj-course-01/000-Contents.ipynb new file mode 100644 index 0000000..ff293b0 --- /dev/null +++ b/dj-course-01/000-Contents.ipynb @@ -0,0 +1,104 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Welcome to DataJoint\n", + "DataJoint for Python 3 is a full-featured relational database programming sublanguage.\n", + "\n", + "It is designed for work with scientific data and computational data pipelines. This tutorial assumes intermediate programming proficiency in Python. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Contents\n", + "\n", + "### 0. Setup \n", + "| | | | |\n", + "|:--|:--|:--|:--|\n", + "| [Set up and Connect](010-Setup.ipynb) |

install datajoint, configure database connection, `dj.config`, authentication, change password, save configuration, secure connection | [Administration](020-Admin.ipynb) |

configure database server, create user accounts, user privileges" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. Work with Individual Tables\n", + "| | | | |\n", + "|:--|:--|:--|:--|\n", + "| [Create a Schema](100-Schema.ipynb) |

`dj.schema` | [Define a Table](110-Table.ipynb) |

table class, simple attributes types, primary and secondary attributes, `insert`, `insert1`, `delete`, `describe`.\n", + "| [Fetch](120-Fetch.ipynb)|

`fetch`, `fetch1`, `head`, `tail`, `len` | [Restrict and project](130-Restrict-Project.ipynb) |

`&`, `-`, `.proj`, `AndList`, restricted `delete`.\n", + "| [More Attribute Types](MoreTypes.ipynb) |

`uuid`, `raw`| [Blobs](130-Blobs.ipynb) |

storing complex data \n", + "| [Attachments](135-Attach.ipynb) |

attaching files | [Lookup Tables](135-Lookup.ipynb) |

specifying fixed contents | \n", + "| [External Storage](160-External.ipynb) |

storing blobs and attachments in external filesystems and AWS S3 | [File Management](170-Filepath.ipynb) |

tracking files in an external repository\n", + "| [Adapted Attribute Types](180-AdaptedTypes.ipynb) |

user-defined attribute types | [Redefining Tables](185-Redefine.ipynb) |

`drop`, `alter`\n", + "| [Secondary Indexes](188-SecondaryIndexes.ipynb) |

secondary indexes | [Transactions](190-Transactions.ipynb) |

Transactions \n", + "| [Log](195-Log.ipynb) |

The log table" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. Work with Multiple Tables\n", + "| | | | |\n", + "|:--|:--|:--|:--|\n", + "| [Schemas and Modules](200-SchemaModules.ipynb) |

correspondence between schemas and modules | [Dependencies](210-Dependencies.ipynb) |

primary and secondary dependencies, referential constraints, cascading deletes\n", + "| [Work with Existing Schemas](220-Existing.ipynb) |

`dj.list_schemas`, `schema.spawn_missing_classes`, `dj.create_virtual_modules` | [Diagramming](230-Diagramming.ipynb) | `dj.Diagram`, graph algebra, multi-schema databases |\n", + "| [Join and Restrict](240-Join.ipynb) |

`*`, using `proj` to control join | [Aggregate](250-Aggregate.ipynb) |

`.aggr`\n", + "| [Hierarchical Relationships](250-Nested.ipynb) |

modeling hierarchical or nested data | [Dimensional Relationships](255-Dimensional.ipynb) |

modeling dimensional relationships \n", + "| [Master-part Relationships](Master-Part.ipynb) |

modeling master-part relationships | [Specialization Relationships](260-Specialization.ipynb) |

modeling specialization relationships |\n", + "| [Derived Dependencies](270-DerivedDependencies.ipynb) |

dependencies on query expressions | [Dependency Properties](274-DependencyProperties.ipynb) |

`unique` and `nullable` dependencies\n", + "| [Association Relationships](276-Associations.ipynb) |

modeling associations between entities | [Cyclic Relationships](278-Cyclic.ipynb) |

modeling cyclic relationships | \n", + "| [Universal sets](280-U.ipynb) |

`dj.U` in restrictions, aggregations, and joins | [Union](282-Union.ipynb) |

`+` \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3. Computations\n", + "| | | | |\n", + "|:--|:--|:--|:--|\n", + "| [Populate](300-SchemaModules.ipynb) |

The `populate` method and the `make` callback in `dj.Imported` and `dj.Computed` tables. | [Distributed Computations](310-Distributed) |

Using `populate` with `reserve_jobs=True`\n", + "| [Jobs Table](320-Jobs.ipynb) |

Working with `schema.jobs` table and `dj.kill` | [Master-Part Computations](330-MasterPart.ipynb) |

Computations in a master-part relationship\n", + "| [Computation Parameters](340-Parameters.ipynb) |

Computation parameters and versions | [Key Source](350-KeySource.ipynb) |

Controlling the scope and granularity of computing jobs with `key_source`\n", + "| [Offline Jobs](360-OfflineJobs.ipynb) |

work with no database connection" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4. Interfaces & Applications\n", + "| | | | |\n", + "|:--|:--|:--|:--|\n", + "| [Export](410-Export.ipynb) |

exporting data for dataset sharing | [Web GUIs](440-WebGUIs.ipynb) |

wen interfaces\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/dj-course-01/010-Setup.ipynb b/dj-course-01/010-Setup.ipynb new file mode 100644 index 0000000..0e6106a --- /dev/null +++ b/dj-course-01/010-Setup.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Setup\n", + "\n", + "## Install DataJoint\n", + "To get started you will need to install `datajoint` from PyPi:\n", + "\n", + "```shell\n", + "$ pip install datajoint\n", + "```\n", + "\n", + "Import datajoint and verify its version. It should be 0.12 or higher. It is a common convention to import datajoint as `dj`:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (external.py, line 166)", + "output_type": "error", + "traceback": [ + "Traceback \u001b[0;36m(most recent call last)\u001b[0m:\n", + " File \u001b[1;32m\"/home/dimitri/.local/lib/python3.7/site-packages/IPython/core/interactiveshell.py\"\u001b[0m, line \u001b[1;32m3326\u001b[0m, in \u001b[1;35mrun_code\u001b[0m\n exec(code_obj, self.user_global_ns, self.user_ns)\n", + " File \u001b[1;32m\"\"\u001b[0m, line \u001b[1;32m1\u001b[0m, in \u001b[1;35m\u001b[0m\n import datajoint as dj\n", + " File \u001b[1;32m\"/home/dimitri/dev/datajoint-python/datajoint/__init__.py\"\u001b[0m, line \u001b[1;32m33\u001b[0m, in \u001b[1;35m\u001b[0m\n from .schema import Schema as schema\n", + "\u001b[0;36m File \u001b[0;32m\"/home/dimitri/dev/datajoint-python/datajoint/schema.py\"\u001b[0;36m, line \u001b[0;32m13\u001b[0;36m, in \u001b[0;35m\u001b[0;36m\u001b[0m\n\u001b[0;31m from .external import ExternalMapping\u001b[0m\n", + "\u001b[0;36m File \u001b[0;32m\"/home/dimitri/dev/datajoint-python/datajoint/external.py\"\u001b[0;36m, line \u001b[0;32m166\u001b[0m\n\u001b[0;31m with open(full_path, 'rb')\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "import datajoint as dj" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Alter.ipynb b/notebooks/Alter.ipynb index a0ba0bb..a595a1d 100644 --- a/notebooks/Alter.ipynb +++ b/notebooks/Alter.ipynb @@ -42,18 +42,20 @@ { "data": { "image/svg+xml": [ - "\n", + "\n", "\n", "%3\n", - "\n", - "\n", + "\n", + "\n", "\n", - "Term\n", - "Exam\n", + "\n", - "\n", - "Term\n", + "\n", + "Exam\n", "\n", "\n", "\n", @@ -66,143 +68,158 @@ "------------------------------\r", "auditorium           \r", "\">\n", - "\n", - "Section\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Term->Section\n", - "\n", - "\n", - "\n", - "\n", - "CurrentTerm\n", - "\n", - "\n", - "CurrentTerm\n", + "\n", + "Section\n", "\n", "\n", "\n", - "\n", - "\n", - "Term->CurrentTerm\n", - "\n", - "\n", "\n", - "\n", + "\n", "Enroll\n", - "\n", - "\n", - "Enroll\n", + "\n", + "Enroll\n", "\n", "\n", "\n", "\n", - "\n", + "\n", "Section->Enroll\n", - "\n", + "\n", "\n", "\n", - "\n", + "\n", "Grade\n", - "\n", - "\n", - "Grade\n", + "\n", + "Grade\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Major\n", + "\n", + "\n", + "Major\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "StudentMajor\n", + "\n", + "\n", + "StudentMajor\n", "\n", "\n", "\n", + "\n", + "\n", + "Enroll->Exam\n", + "\n", + "\n", "\n", - "\n", + "\n", "Enroll->Grade\n", - "\n", + "\n", "\n", - "\n", - "\n", - "Department\n", - "\n", + "\n", + "LetterGrade\n", + "\n", - "\n", - "Department\n", + "\n", + "LetterGrade\n", "\n", "\n", "\n", + "\n", + "\n", + "LetterGrade->Grade\n", + "\n", + "\n", "\n", - "\n", + "\n", "Course\n", - "\n", - "\n", - "Course\n", + "\n", + "Course\n", "\n", "\n", "\n", - "\n", + "\n", "\n", - "Department->Course\n", - "\n", + "Course->Section\n", + "\n", "\n", - "\n", + "\n", "\n", - "StudentMajor\n", - "CurrentTerm\n", + "\n", - "\n", - "StudentMajor\n", + "\n", + "CurrentTerm\n", "\n", "\n", "\n", - "\n", - "\n", - "Department->StudentMajor\n", - "\n", - "\n", - "\n", - "\n", - "LetterGrade\n", - "\n", + "\n", + "Department\n", + "\n", - "\n", - "LetterGrade\n", + "\n", + "Department\n", "\n", "\n", "\n", - "\n", + "\n", + "\n", + "Department->Major\n", + "\n", + "\n", + "\n", "\n", - "LetterGrade->Grade\n", - "\n", + "Department->StudentMajor\n", + "\n", "\n", - "\n", + "\n", "\n", - "Course->Section\n", - "\n", + "Department->Course\n", + "\n", "\n", "\n", - "\n", + "\n", "Student\n", - "\n", - "\n", - "Student\n", + "\n", + "Student\n", "\n", "\n", "\n", - "\n", + "\n", "\n", - "Student->Enroll\n", - "\n", + "Student->Major\n", + "\n", "\n", "\n", "\n", "Student->StudentMajor\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "Student->Enroll\n", + "\n", + "\n", + "\n", + "\n", + "Term\n", + "\n", + "\n", + "Term\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Term->Section\n", + "\n", + "\n", + "\n", + "\n", + "Term->CurrentTerm\n", + "\n", "\n", "\n", "" ], "text/plain": [ - "" + "" ] }, "execution_count": 2, @@ -267,40 +310,10 @@ " \"\"\"" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's change the definition to record the exam date too" - ] - }, { "cell_type": "code", "execution_count": 4, "metadata": {}, - "outputs": [], - "source": [ - "@schema\n", - "class Exam(dj.Manual):\n", - " definition = \"\"\"\n", - " -> Enroll\n", - " ---\n", - " exam_date : date\n", - " score : decimal(5,2) # percent of total \n", - " \"\"\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Even though we updated the `definition` in the class, the change is not reflected on the server:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, "outputs": [ { "data": { @@ -378,23 +391,82 @@ "

section

\n", " \n", "
\n", - "

score

\n", + "

exam_date

\n", + " \n", + "
\n", + "

exam_score

\n", " percent of total\n", "
\n", - " \n", + " 1016\n", + "MATH\n", + "2280\n", + "2018\n", + "Fall\n", + "a\n", + "None\n", + "86.0001067\n", + "CS\n", + "2100\n", + "2018\n", + "Fall\n", + "a\n", + "None\n", + "13.0001084\n", + "MATH\n", + "1250\n", + "2018\n", + "Fall\n", + "a\n", + "2019-04-30\n", + "65.0001201\n", + "BIOL\n", + "2021\n", + "2018\n", + "Fall\n", + "a\n", + "None\n", + "22.0001204\n", + "CS\n", + "1030\n", + "2018\n", + "Fall\n", + "d\n", + "2019-04-30\n", + "42.0001484\n", + "PHYS\n", + "2040\n", + "2018\n", + "Fall\n", + "a\n", + "None\n", + "83.0001515\n", + "PHYS\n", + "2140\n", + "2018\n", + "Fall\n", + "a\n", + "None\n", + "13.000 \n", " \n", - " \n", - "

Total: 0

\n", + "

...

\n", + "

Total: 120

\n", " " ], "text/plain": [ - "*student_id *dept *course *term_year *term *section score \n", - "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +-------+\n", - "\n", - " (Total: 0)" + "*student_id *dept *course *term_year *term *section exam_date exam_score \n", + "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +------------+ +------------+\n", + "1016 MATH 2280 2018 Fall a None 86.000 \n", + "1067 CS 2100 2018 Fall a None 13.000 \n", + "1084 MATH 1250 2018 Fall a 2019-04-30 65.000 \n", + "1201 BIOL 2021 2018 Fall a None 22.000 \n", + "1204 CS 1030 2018 Fall d 2019-04-30 42.000 \n", + "1484 PHYS 2040 2018 Fall a None 83.000 \n", + "1515 PHYS 2140 2018 Fall a None 13.000 \n", + " ...\n", + " (Total: 120)" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -403,646 +475,387 @@ "Exam()" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can examine the definition on the server using the `describe` method:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-> Enroll\n", - "---\n", - "score : decimal(5,2) # percent of total\n", - "\n" - ] - } - ], - "source": [ - "Exam.describe();" - ] - }, { "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - " -> Enroll\n", - " ---\n", - " exam_date : date\n", - " score : decimal(5,2) # percent of total \n", - " \n" - ] - } - ], - "source": [ - "print(Exam.definition)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "One solution is to simply drop the table and declare it again, which is fine when it contains no valuable data. But let's consider the case when the table is already populated and we wish to keep the existing data. \n", - "\n", - "First, let's insert some exam entries:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "# pick 100 random enrollments from the current term\n", - "import random\n", - "keys = random.sample(((Enroll - Exam) & CurrentTerm).fetch('KEY'), 100)\n", - "# assign random scores\n", - "for key in keys:\n", - " Exam.insert1(dict(key, score=random.randint(0,10000)/100))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can alter the `Exam` table with the new definition:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

dept

\n", - " abbreviated department name, e.g. BIOL\n", - "
\n", - "

course

\n", - " course number, e.g. 1010\n", - "
\n", - "

term_year

\n", - " \n", - "
\n", - "

term

\n", - " \n", - "
\n", - "

section

\n", - " \n", - "
\n", - "

score

\n", - " percent of total\n", - "
1069PHYS21002018Falla79.15
1084MATH12502018Falla44.69
1164BIOL10062018Fallb78.62
\n", - "

...

\n", - "

Total: 100

\n", - " " - ], - "text/plain": [ - "*student_id *dept *course *term_year *term *section score \n", - "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +-------+\n", - "1069 PHYS 2100 2018 Fall a 79.15 \n", - "1084 MATH 1250 2018 Fall a 44.69 \n", - "1164 BIOL 1006 2018 Fall b 78.62 \n", - " ...\n", - " (Total: 100)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Exam()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can now use the `alter` method to apply the new definition:" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tADD `exam_date` date NOT NULL AFTER `section`,\n", - "\tMODIFY `score` decimal(5,2) NOT NULL COMMENT \"percent of total\" AFTER `exam_date`\n", - "\n", - "Execute? [yes, no]: yes\n" - ] - }, - { - "ename": "InternalError", - "evalue": "(1292, \"Incorrect date value: '0000-00-00' for column 'exam_date' at row 1\")", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mInternalError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mExam\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0malter\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[0m", - "\u001b[0;32m~/dev/datajoint-python/datajoint/table.py\u001b[0m in \u001b[0;36malter\u001b[0;34m(self, prompt, context)\u001b[0m\n\u001b[1;32m 102\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstore\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mexternal_stores\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mschemas\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdatabase\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexternal\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mstore\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 104\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msql\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 105\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mpymysql\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mOperationalError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merror\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 106\u001b[0m \u001b[0;31m# skip if no create privilege\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/dev/datajoint-python/datajoint/connection.py\u001b[0m in \u001b[0;36mquery\u001b[0;34m(self, query, args, as_dict, suppress_warnings, reconnect)\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0;31m# suppress all warnings arising from underlying SQL library\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 147\u001b[0m \u001b[0mwarnings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimplefilter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"ignore\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 148\u001b[0;31m \u001b[0mcur\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexecute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 149\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mInterfaceError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mOperationalError\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 150\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_connection_error\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mreconnect\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/cursors.py\u001b[0m in \u001b[0;36mexecute\u001b[0;34m(self, query, args)\u001b[0m\n\u001b[1;32m 168\u001b[0m \u001b[0mquery\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmogrify\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 169\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 170\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_query\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 171\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_executed\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mquery\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 172\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/cursors.py\u001b[0m in \u001b[0;36m_query\u001b[0;34m(self, q)\u001b[0m\n\u001b[1;32m 326\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_last_executed\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mq\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 327\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_clear_result\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[0;32m--> 328\u001b[0;31m \u001b[0mconn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mq\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 329\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_do_get_result\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 330\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrowcount\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/connections.py\u001b[0m in \u001b[0;36mquery\u001b[0;34m(self, sql, unbuffered)\u001b[0m\n\u001b[1;32m 515\u001b[0m \u001b[0msql\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msql\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencoding\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'surrogateescape'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 516\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_execute_command\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mCOMMAND\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCOM_QUERY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msql\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 517\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_affected_rows\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_read_query_result\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0munbuffered\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0munbuffered\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 518\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_affected_rows\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 519\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/connections.py\u001b[0m in \u001b[0;36m_read_query_result\u001b[0;34m(self, unbuffered)\u001b[0m\n\u001b[1;32m 730\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 731\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mMySQLResult\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 732\u001b[0;31m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\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[0m\u001b[1;32m 733\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_result\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 734\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mserver_status\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/connections.py\u001b[0m in \u001b[0;36mread\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1073\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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 1074\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1075\u001b[0;31m \u001b[0mfirst_packet\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_read_packet\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[0m\u001b[1;32m 1076\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1077\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfirst_packet\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_ok_packet\u001b[0m\u001b[0;34m(\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[0;32m~/.local/lib/python3.6/site-packages/pymysql/connections.py\u001b[0m in \u001b[0;36m_read_packet\u001b[0;34m(self, packet_type)\u001b[0m\n\u001b[1;32m 682\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 683\u001b[0m \u001b[0mpacket\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpacket_type\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbuff\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencoding\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 684\u001b[0;31m \u001b[0mpacket\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheck_error\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[0m\u001b[1;32m 685\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mpacket\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/protocol.py\u001b[0m in \u001b[0;36mcheck_error\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 218\u001b[0m \u001b[0merrno\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_uint16\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 219\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mDEBUG\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"errno =\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0merrno\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 220\u001b[0;31m \u001b[0merr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_mysql_exception\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 221\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 222\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdump\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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[0;32m~/.local/lib/python3.6/site-packages/pymysql/err.py\u001b[0m in \u001b[0;36mraise_mysql_exception\u001b[0;34m(data)\u001b[0m\n\u001b[1;32m 107\u001b[0m \u001b[0merrval\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'utf-8'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'replace'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 108\u001b[0m \u001b[0merrorclass\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0merror_map\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merrno\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mInternalError\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 109\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merrorclass\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merrno\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0merrval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mInternalError\u001b[0m: (1292, \"Incorrect date value: '0000-00-00' for column 'exam_date' at row 1\")" - ] - } - ], - "source": [ - "Exam.alter()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Oh! New attributes cannot be added to tables with existing data without providing a default value. Let's update the definition to allow `exam_date` to be empty (default to `null`) and alter the table again." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "@schema\n", - "class Exam(dj.Manual):\n", - " definition = \"\"\"\n", - " -> Enroll \n", - " ---\n", - " exam_date = null: date \n", - " score : decimal(5,2) # percent of total \n", - " \"\"\"" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tADD `exam_date` date DEFAULT NULL AFTER `section`,\n", - "\tMODIFY `score` decimal(5,2) NOT NULL COMMENT \"percent of total\" AFTER `exam_date`\n", - "\n", - "Execute? [yes, no]: yes\n", - "Table altered\n" - ] - } - ], - "source": [ - "Exam.alter()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

dept

\n", - " abbreviated department name, e.g. BIOL\n", - "
\n", - "

course

\n", - " course number, e.g. 1010\n", - "
\n", - "

term_year

\n", - " \n", - "
\n", - "

term

\n", - " \n", - "
\n", - "

section

\n", - " \n", - "
\n", - "

exam_date

\n", - " \n", - "
\n", - "

score

\n", - " percent of total\n", - "
1069PHYS21002018FallaNone79.15
1084MATH12502018FallaNone44.69
1164BIOL10062018FallbNone78.62
\n", - "

...

\n", - "

Total: 100

\n", - " " + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "\n", + "Exam\n", + "\n", + "\n", + "Exam\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Section\n", + "\n", + "\n", + "Section\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Enroll\n", + "\n", + "\n", + "Enroll\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Section->Enroll\n", + "\n", + "\n", + "\n", + "\n", + "Grade\n", + "\n", + "\n", + "Grade\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Major\n", + "\n", + "\n", + "Major\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "StudentMajor\n", + "\n", + "\n", + "StudentMajor\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Enroll->Exam\n", + "\n", + "\n", + "\n", + "\n", + "Enroll->Grade\n", + "\n", + "\n", + "\n", + "\n", + "LetterGrade\n", + "\n", + "\n", + "LetterGrade\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "LetterGrade->Grade\n", + "\n", + "\n", + "\n", + "\n", + "Course\n", + "\n", + "\n", + "Course\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Course->Section\n", + "\n", + "\n", + "\n", + "\n", + "CurrentTerm\n", + "\n", + "\n", + "CurrentTerm\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Department\n", + "\n", + "\n", + "Department\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Department->Major\n", + "\n", + "\n", + "\n", + "\n", + "Department->StudentMajor\n", + "\n", + "\n", + "\n", + "\n", + "Department->Course\n", + "\n", + "\n", + "\n", + "\n", + "Student\n", + "\n", + "\n", + "Student\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Student->Major\n", + "\n", + "\n", + "\n", + "\n", + "Student->StudentMajor\n", + "\n", + "\n", + "\n", + "\n", + "Student->Enroll\n", + "\n", + "\n", + "\n", + "\n", + "Term\n", + "\n", + "\n", + "Term\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Term->Section\n", + "\n", + "\n", + "\n", + "\n", + "Term->CurrentTerm\n", + "\n", + "\n", + "\n", + "" ], "text/plain": [ - "*student_id *dept *course *term_year *term *section exam_date score \n", - "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +-----------+ +-------+\n", - "1069 PHYS 2100 2018 Fall a None 79.15 \n", - "1084 MATH 1250 2018 Fall a None 44.69 \n", - "1164 BIOL 1006 2018 Fall b None 78.62 \n", - " ...\n", - " (Total: 100)" + "" ] }, - "execution_count": 13, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "Exam()" + "dj.Diagram(schema)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Now let's add some grades for today's exam:" + "Let's change the definition to record the exam date too" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "from datetime import datetime\n", - "today = datetime.now().date().isoformat()" + "@schema\n", + "class Exam(dj.Manual):\n", + " definition = \"\"\"\n", + " -> Enroll\n", + " ---\n", + " exam_date : date\n", + " score : decimal(5,2) # percent of total \n", + " \"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Even though we updated the `definition` in the class, the change is not reflected on the server:" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# pick 20 random enrollments from the current term\n", - "keys = random.sample(((Enroll - Exam) & CurrentTerm).fetch('KEY'), 20)\n", - "# assign random scores\n", - "for key in keys:\n", - " Exam.insert1(dict(key, score=random.randint(0,10000)/100, exam_date=today))" + "Exam()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can examine the definition on the server using the `describe` method:" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

dept

\n", - " abbreviated department name, e.g. BIOL\n", - "
\n", - "

course

\n", - " course number, e.g. 1010\n", - "
\n", - "

term_year

\n", - " \n", - "
\n", - "

term

\n", - " \n", - "
\n", - "

section

\n", - " \n", - "
\n", - "

exam_date

\n", - " \n", - "
\n", - "

score

\n", - " percent of total\n", - "
1069PHYS21002018FallaNone79.15
1084MATH12502018FallaNone44.69
1088CS31002018Falla2019-04-2317.70
\n", - "

...

\n", - "

Total: 120

\n", - " " - ], - "text/plain": [ - "*student_id *dept *course *term_year *term *section exam_date score \n", - "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +------------+ +-------+\n", - "1069 PHYS 2100 2018 Fall a None 79.15 \n", - "1084 MATH 1250 2018 Fall a None 44.69 \n", - "1088 CS 3100 2018 Fall a 2019-04-23 17.70 \n", - " ...\n", - " (Total: 120)" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], + "source": [ + "Exam.describe();" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ - "Exam()" + "Exam.heading" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Now let's say we want to rename `score` into `exam_score`:" + "One solution is to simply drop the table and declare it again, which is fine when it contains no valuable data. But let's consider the case when the table is already populated and we wish to keep the existing data. \n", + "\n", + "First, let's insert some exam entries:" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "@schema\n", - "class Exam(dj.Manual):\n", - " definition = \"\"\"\n", - " -> Enroll \n", - " ---\n", - " exam_date = null: date \n", - " exam_score : decimal(5,2) # percent of total \n", - " \"\"\"" + "# pick 100 random enrollments from the current term\n", + "import random\n", + "keys = random.sample(((Enroll - Exam) & CurrentTerm).fetch('KEY'), 100)\n", + "# assign random scores\n", + "for key in keys:\n", + " Exam.insert1(dict(key, score=random.randint(0,10000)/100))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can alter the `Exam` table with the new definition:" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tDROP `score`,\n", - "\tADD `exam_score` decimal(5,2) NOT NULL COMMENT \"percent of total\" AFTER `exam_date`\n", - "\n", - "Execute? [yes, no]: no\n" - ] - } - ], + "outputs": [], + "source": [ + "Exam()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now use the `alter` method to apply the new definition:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dj.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], "source": [ - "# Say NO!\n", "Exam.alter()" ] }, @@ -1050,14 +863,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Note that rather than renaming, `alter` attempted to drop the old attribute and add the new one. \n", - "\n", - "To rename, we must indicate the old attribute name in curly brackets as the first thing in the attribute comment:" + "Oh! New attributes cannot be added to tables with existing data without providing a default value. Let's update the definition to allow `exam_date` to be empty (default to `null`) and alter the table again." ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1067,160 +878,148 @@ " -> Enroll \n", " ---\n", " exam_date = null: date \n", - " exam_score : decimal(5,2) # {score} percent of total \n", + " score : decimal(5,2) # percent of total \n", " \"\"\"" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tCHANGE `score` `exam_score` decimal(5,2) NOT NULL COMMENT \"{score} percent of total\" \n", - "\n", - "Execute? [yes, no]: yes\n", - "Table altered\n" - ] - } - ], + "outputs": [], "source": [ "Exam.alter()" ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

dept

\n", - " abbreviated department name, e.g. BIOL\n", - "
\n", - "

course

\n", - " course number, e.g. 1010\n", - "
\n", - "

term_year

\n", - " \n", - "
\n", - "

term

\n", - " \n", - "
\n", - "

section

\n", - " \n", - "
\n", - "

exam_date

\n", - " \n", - "
\n", - "

exam_score

\n", - " {score} percent of total\n", - "
1069PHYS21002018FallaNone79.15
1084MATH12502018FallaNone44.69
1088CS31002018Falla2019-04-2317.70
\n", - "

...

\n", - "

Total: 120

\n", - " " - ], - "text/plain": [ - "*student_id *dept *course *term_year *term *section exam_date exam_score \n", - "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +------------+ +------------+\n", - "1069 PHYS 2100 2018 Fall a None 79.15 \n", - "1084 MATH 1250 2018 Fall a None 44.69 \n", - "1088 CS 3100 2018 Fall a 2019-04-23 17.70 \n", - " ...\n", - " (Total: 120)" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], + "source": [ + "Exam()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's add some grades for today's exam:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from datetime import datetime\n", + "today = datetime.now().date().isoformat()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "today" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# pick 20 random enrollments from the current term\n", + "keys = random.sample(((Enroll - Exam) & CurrentTerm).fetch('KEY'), 20)\n", + "# assign random scores\n", + "for key in keys:\n", + " Exam.insert1(dict(key, score=random.randint(0,10000)/100, exam_date=today))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Exam()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's say we want to rename `score` into `exam_score`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Exam(dj.Manual):\n", + " definition = \"\"\"\n", + " -> Enroll \n", + " ---\n", + " exam_date = null: date \n", + " exam_score : decimal(5,2) # percent of total \n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Say NO!\n", + "Exam.alter()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that rather than renaming, `alter` attempted to drop the old attribute and add the new one. \n", + "\n", + "To rename, we must indicate the old attribute name in curly brackets as the first thing in the attribute comment:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Exam(dj.Manual):\n", + " definition = \"\"\"\n", + " -> Enroll \n", + " ---\n", + " exam_score : decimal(5,2) # percent of total \n", + " exam_date = null: date \n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Exam.alter()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "Exam()" ] @@ -1234,28 +1033,16 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-> Enroll\n", - "---\n", - "exam_date=null : date \n", - "exam_score : decimal(5,2) # {score} percent of total\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "Exam.describe();" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1265,48 +1052,34 @@ " -> Enroll \n", " ---\n", " exam_date = null: date \n", - " exam_score : decimal(5,2) # percent of total \n", + " exam_score : decimal(6,3) # percent of total \n", + " photocopy: longb \n", " \"\"\"" ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tMODIFY `exam_score` decimal(5,2) NOT NULL COMMENT \"percent of total\" \n", - "\n", - "Execute? [yes, no]: yes\n", - "Table altered\n" - ] - } - ], + "outputs": [], "source": [ "Exam.alter()" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "-> Enroll\n", - "---\n", - "exam_date=null : date \n", - "exam_score : decimal(5,2) # percent of total\n", - "\n" - ] - } - ], + "outputs": [], + "source": [ + "Exam()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "Exam.describe();" ] @@ -1322,7 +1095,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1338,154 +1111,18 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tMODIFY `exam_score` tinyint unsigned NOT NULL COMMENT \"percent of total\" \n", - "\n", - "Execute? [yes, no]: yes\n", - "Table altered\n" - ] - } - ], + "outputs": [], "source": [ "Exam.alter()" ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

dept

\n", - " abbreviated department name, e.g. BIOL\n", - "
\n", - "

course

\n", - " course number, e.g. 1010\n", - "
\n", - "

term_year

\n", - " \n", - "
\n", - "

term

\n", - " \n", - "
\n", - "

section

\n", - " \n", - "
\n", - "

exam_date

\n", - " \n", - "
\n", - "

exam_score

\n", - " percent of total\n", - "
1069PHYS21002018FallaNone79
1084MATH12502018FallaNone45
1088CS31002018Falla2019-04-2318
\n", - "

...

\n", - "

Total: 120

\n", - " " - ], - "text/plain": [ - "*student_id *dept *course *term_year *term *section exam_date exam_score \n", - "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +------------+ +------------+\n", - "1069 PHYS 2100 2018 Fall a None 79 \n", - "1084 MATH 1250 2018 Fall a None 45 \n", - "1088 CS 3100 2018 Fall a 2019-04-23 18 \n", - " ...\n", - " (Total: 120)" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "Exam()" ] @@ -1499,7 +1136,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1515,48 +1152,16 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tMODIFY `exam_score` decimal(3,2) NOT NULL COMMENT \"percent of total\" \n", - "\n", - "Execute? [yes, no]: yes\n" - ] - }, - { - "ename": "DataError", - "evalue": "(1264, \"Out of range value for column 'exam_score' at row 1\")", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mDataError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mExam\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0malter\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[0m", - "\u001b[0;32m~/dev/datajoint-python/datajoint/table.py\u001b[0m in \u001b[0;36malter\u001b[0;34m(self, prompt, context)\u001b[0m\n\u001b[1;32m 102\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mstore\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mexternal_stores\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mschemas\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdatabase\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexternal\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mstore\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 104\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msql\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 105\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mpymysql\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mOperationalError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merror\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 106\u001b[0m \u001b[0;31m# skip if no create privilege\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/dev/datajoint-python/datajoint/connection.py\u001b[0m in \u001b[0;36mquery\u001b[0;34m(self, query, args, as_dict, suppress_warnings, reconnect)\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0;31m# suppress all warnings arising from underlying SQL library\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 147\u001b[0m \u001b[0mwarnings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimplefilter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"ignore\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 148\u001b[0;31m \u001b[0mcur\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexecute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 149\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mInterfaceError\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mOperationalError\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 150\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_connection_error\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mreconnect\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/cursors.py\u001b[0m in \u001b[0;36mexecute\u001b[0;34m(self, query, args)\u001b[0m\n\u001b[1;32m 168\u001b[0m \u001b[0mquery\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmogrify\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 169\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 170\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_query\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 171\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_executed\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mquery\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 172\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/cursors.py\u001b[0m in \u001b[0;36m_query\u001b[0;34m(self, q)\u001b[0m\n\u001b[1;32m 326\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_last_executed\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mq\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 327\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_clear_result\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[0;32m--> 328\u001b[0;31m \u001b[0mconn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mq\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 329\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_do_get_result\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 330\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrowcount\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/connections.py\u001b[0m in \u001b[0;36mquery\u001b[0;34m(self, sql, unbuffered)\u001b[0m\n\u001b[1;32m 515\u001b[0m \u001b[0msql\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msql\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencoding\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'surrogateescape'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 516\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_execute_command\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mCOMMAND\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCOM_QUERY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msql\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 517\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_affected_rows\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_read_query_result\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0munbuffered\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0munbuffered\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 518\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_affected_rows\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 519\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/connections.py\u001b[0m in \u001b[0;36m_read_query_result\u001b[0;34m(self, unbuffered)\u001b[0m\n\u001b[1;32m 730\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 731\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mMySQLResult\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 732\u001b[0;31m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\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[0m\u001b[1;32m 733\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_result\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 734\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mserver_status\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/connections.py\u001b[0m in \u001b[0;36mread\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1073\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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 1074\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1075\u001b[0;31m \u001b[0mfirst_packet\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_read_packet\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[0m\u001b[1;32m 1076\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1077\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfirst_packet\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_ok_packet\u001b[0m\u001b[0;34m(\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[0;32m~/.local/lib/python3.6/site-packages/pymysql/connections.py\u001b[0m in \u001b[0;36m_read_packet\u001b[0;34m(self, packet_type)\u001b[0m\n\u001b[1;32m 682\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 683\u001b[0m \u001b[0mpacket\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpacket_type\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbuff\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mencoding\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 684\u001b[0;31m \u001b[0mpacket\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheck_error\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[0m\u001b[1;32m 685\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mpacket\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 686\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.local/lib/python3.6/site-packages/pymysql/protocol.py\u001b[0m in \u001b[0;36mcheck_error\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 218\u001b[0m \u001b[0merrno\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_uint16\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 219\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mDEBUG\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"errno =\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0merrno\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 220\u001b[0;31m \u001b[0merr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_mysql_exception\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 221\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 222\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdump\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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[0;32m~/.local/lib/python3.6/site-packages/pymysql/err.py\u001b[0m in \u001b[0;36mraise_mysql_exception\u001b[0;34m(data)\u001b[0m\n\u001b[1;32m 107\u001b[0m \u001b[0merrval\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'utf-8'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'replace'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 108\u001b[0m \u001b[0merrorclass\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0merror_map\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merrno\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mInternalError\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 109\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merrorclass\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merrno\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0merrval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mDataError\u001b[0m: (1264, \"Out of range value for column 'exam_score' at row 1\")" - ] - } - ], + "outputs": [], "source": [ "Exam.alter()" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1571,155 +1176,19 @@ ] }, { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tMODIFY `exam_score` decimal(5,2) NOT NULL COMMENT \"percent of total\" \n", - "\n", - "Execute? [yes, no]: yes\n", - "Table altered\n" - ] - } - ], + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "Exam.alter()" ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

dept

\n", - " abbreviated department name, e.g. BIOL\n", - "
\n", - "

course

\n", - " course number, e.g. 1010\n", - "
\n", - "

term_year

\n", - " \n", - "
\n", - "

term

\n", - " \n", - "
\n", - "

section

\n", - " \n", - "
\n", - "

exam_date

\n", - " \n", - "
\n", - "

exam_score

\n", - " percent of total\n", - "
1069PHYS21002018FallaNone79.00
1084MATH12502018FallaNone45.00
1088CS31002018Falla2019-04-2318.00
\n", - "

...

\n", - "

Total: 120

\n", - " " - ], - "text/plain": [ - "*student_id *dept *course *term_year *term *section exam_date exam_score \n", - "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +------------+ +------------+\n", - "1069 PHYS 2100 2018 Fall a None 79.00 \n", - "1084 MATH 1250 2018 Fall a None 45.00 \n", - "1088 CS 3100 2018 Fall a 2019-04-23 18.00 \n", - " ...\n", - " (Total: 120)" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# restored to higher precision but fractional part has been lost:\n", "Exam()" @@ -1734,7 +1203,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -1745,181 +1214,32 @@ " -> Enroll \n", " ---\n", " exam_score : decimal(5,2) # percent of total \n", - " exam_date = null: date \n", " \"\"\"" ] }, { "cell_type": "code", - "execution_count": 35, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "ALTER TABLE `university`.`exam`\n", - "\tMODIFY `exam_score` decimal(5,2) NOT NULL COMMENT \"percent of total\" AFTER `section`,\n", - "\tMODIFY `exam_date` date DEFAULT NULL AFTER `exam_score`,\n", - "\tCOMMENT=\"Exam taken by a student enrolled in a course section and the grade\"\n", - "\n", - "Execute? [yes, no]: yes\n", - "Table altered\n" - ] - } - ], + "outputs": [], "source": [ "Exam.alter()" ] }, { "cell_type": "code", - "execution_count": 36, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " Exam taken by a student enrolled in a course section and the grade\n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

dept

\n", - " abbreviated department name, e.g. BIOL\n", - "
\n", - "

course

\n", - " course number, e.g. 1010\n", - "
\n", - "

term_year

\n", - " \n", - "
\n", - "

term

\n", - " \n", - "
\n", - "

section

\n", - " \n", - "
\n", - "

exam_score

\n", - " percent of total\n", - "
\n", - "

exam_date

\n", - " \n", - "
1069PHYS21002018Falla79.00None
1084MATH12502018Falla45.00None
1088CS31002018Falla18.002019-04-23
\n", - "

...

\n", - "

Total: 120

\n", - " " - ], - "text/plain": [ - "*student_id *dept *course *term_year *term *section exam_score exam_date \n", - "+------------+ +------+ +--------+ +-----------+ +------+ +---------+ +------------+ +------------+\n", - "1069 PHYS 2100 2018 Fall a 79.00 None \n", - "1084 MATH 1250 2018 Fall a 45.00 None \n", - "1088 CS 3100 2018 Fall a 18.00 2019-04-23 \n", - " ...\n", - " (Total: 120)" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "Exam()" ] }, { "cell_type": "code", - "execution_count": 37, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "`university`.`exam` (120 tuples)\n", - "Proceed? [yes, No]: yes\n", - "Tables dropped. Restart kernel.\n" - ] - } - ], + "outputs": [], "source": [ "#clean up\n", "Exam.drop()" diff --git a/notebooks/Filepaths.ipynb b/notebooks/Filepaths.ipynb index 88ac8c9..633f669 100644 --- a/notebooks/Filepaths.ipynb +++ b/notebooks/Filepaths.ipynb @@ -15,24 +15,70 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "schema.drop()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "schema = dj.schema('dimitri_filepath')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Connecting dimitri@localhost:3306\n" - ] + "data": { + "text/plain": [ + "['dimitri_alter',\n", + " 'dimitri_attach',\n", + " 'dimitri_blob',\n", + " 'dimitri_blobs',\n", + " 'dimitri_filepath',\n", + " 'dimitri_nphoton',\n", + " 'dimitri_nwb',\n", + " 'dimitri_schema',\n", + " 'dimitri_test',\n", + " 'dimitri_university',\n", + " 'dimitri_uuid',\n", + " 'test_attach',\n", + " 'test_filepath',\n", + " 'test_mikkel',\n", + " 'test_orders',\n", + " 'test_parse',\n", + " 'test_question001',\n", + " 'test_question002',\n", + " 'university']" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "schema = dj.schema('test_filepath')" + "dj.list_schemas()" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -60,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -77,7 +123,31 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9edffe4b13144cd9af50cc58ce890e66", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Image(value=b'https://www.python.org/static/community_logos/python-logo-master-v3-TM.png', format='url')" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Image.from_url(logos['python'])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -93,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -163,9 +233,13 @@ " bcm\n", "https://upload.wikimedia.org/wikipedia/commons/5/5d/Baylor_College_of_Medicine_Logo.pngdatajoint\n", "https://datajoint.io/static/images/DJiotitle.pngpni\n", - "https://vathes.com/2018/05/24/Princeton-Neuroscience-Institute-Partners-with-Vathes-to-Support-the-Adoption-of-DataJoint/PNI%20logo.png \n", + "https://vathes.com/2018/05/24/Princeton-Neuroscience-Institute-Partners-with-Vathes-to-Support-the-Adoption-of-DataJoint/PNI%20logo.pngpydata\n", + "https://pydata.org/wp-content/uploads/2018/10/pydata-logo.pngpython\n", + "https://www.python.org/static/community_logos/python-logo-master-v3-TM.pngucsd\n", + "https://upload.wikimedia.org/wikipedia/commons/f/f6/UCSD_logo.pngutah\n", + "https://umc.utah.edu/wp-content/uploads/sites/15/2015/01/Ulogo_400p.png \n", " \n", - "

...

\n", + " \n", "

Total: 7

\n", " " ], @@ -175,11 +249,14 @@ "bcm https://upload\n", "datajoint https://datajo\n", "pni https://vathes\n", - " ...\n", + "pydata https://pydata\n", + "python https://www.py\n", + "ucsd https://upload\n", + "utah https://umc.ut\n", " (Total: 7)" ] }, - "execution_count": 5, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -190,7 +267,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -207,18 +284,20 @@ " path = os.path.join(dj.config['stores']['remote']['stage'], 'organizations', 'logos')\n", " \n", " def make(self, key):\n", + " # create the subfolder and download the logo into local_file \n", " os.makedirs(self.path, exist_ok=True)\n", " url = (Organization & key).fetch1('logo_url')\n", " local_file = os.path.join(self.path, key['organization'] + os.path.splitext(url)[1])\n", " print(local_file)\n", " with open(local_file, 'wb') as f:\n", " f.write(requests.get(url).content)\n", + " # sync up\n", " self.insert1(dict(key, logo_image=local_file)) " ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -226,7 +305,12 @@ "output_type": "stream", "text": [ "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png\n", - "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png\n" + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pni.png\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pydata.png\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/python.png\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/ucsd.png\n", + "/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/utah.png\n" ] } ], @@ -236,7 +320,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -306,9 +390,13 @@ " pydata\n", "=BLOB=utah\n", "=BLOB=datajoint\n", + "=BLOB=ucsd\n", + "=BLOB=pni\n", + "=BLOB=python\n", + "=BLOB=bcm\n", "=BLOB= \n", " \n", - "

...

\n", + " \n", "

Total: 7

\n", " " ], @@ -318,11 +406,14 @@ "pydata =BLOB= \n", "utah =BLOB= \n", "datajoint =BLOB= \n", - " ...\n", + "ucsd =BLOB= \n", + "pni =BLOB= \n", + "python =BLOB= \n", + "bcm =BLOB= \n", " (Total: 7)" ] }, - "execution_count": 10, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -333,7 +424,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -355,7 +446,7 @@ " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png'}]" ] }, - "execution_count": 11, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -366,7 +457,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -377,7 +468,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -386,7 +477,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -402,7 +493,7 @@ " dtype=object)" ] }, - "execution_count": 14, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -413,18 +504,18 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "004ccb36b6a34dc48e961db8724db181", + "model_id": "3598ff4bf5fa401fb985cad84ec5d05e", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "Image(value=b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR\\x00\\x00\\x02Y\\x00\\x00\\x00\\xcb\\x08\\x06\\x00\\x00\\x00]\\xc9\\x86&\\x…" + "Image(value=b'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR\\x00\\x00\\x00\\xfb\\x00\\x00\\x00\\xc9\\x08\\x03\\x00\\x00\\x00\\xd2\\x1e\\…" ] }, "metadata": {}, @@ -432,12 +523,12 @@ } ], "source": [ - "Image.from_file(paths[5])" + "Image.from_file(paths[4])" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -445,7 +536,7 @@ "output_type": "stream", "text": [ "About to delete:\n", - "`test_filepath`.`_logo`: 2 items\n", + "`dimitri_filepath`.`_logo`: 2 items\n", "Proceed? [yes, No]: yes\n", "Committed.\n" ] @@ -457,13 +548,147 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "ext = schema.external['remote']" ] }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

filepath

\n", + " relative filepath used in the filepath datatype\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
3fd4b79b-9fdd-95c0-4074-68614d97f7e1162organizations/logos/pydata.pngbc56979a-0b38-1a79-1dd5-9713198a87fb2019-07-30 16:50:40
56c820a9-e83c-02c9-8e76-7ba90819258813216organizations/logos/utah.png1c755e4b-a65f-5576-352e-729f0c5987da2019-07-30 16:50:41
6e7ba0be-2171-a2ab-163e-ff12b0943e8e36444organizations/logos/datajoint.png9e902f2f-726a-2da5-0a24-ee3b97892f8a2019-07-30 16:50:38
81dc7dae-bebc-6d38-b891-c48eee8e340a33734organizations/logos/ucsd.png914f5b55-ea69-7489-d45b-031bec3ecaa52019-07-30 16:50:40
8c25c65d-506d-f382-0e36-88e1f6057ea36293organizations/logos/pni.png0d59845d-5c75-24f8-20c8-9637517ed6a72019-07-30 16:50:39
f35b5a91-38cb-bc7f-ef17-b2ce94bb013183564organizations/logos/python.png3cf229ee-dc09-2549-277e-8859aad2fca52019-07-30 16:50:40
f97ea212-5794-926a-d852-deffc0f10bba227965organizations/logos/bcm.png10ee4617-a63f-61ba-2807-35a266a9f4882019-07-30 16:50:38
\n", + " \n", + "

Total: 7

\n", + " " + ], + "text/plain": [ + "*hash size filepath contents_hash timestamp \n", + "+------------+ +--------+ +------------+ +------------+ +------------+\n", + "3fd4b79b-9fdd- 162 organizations/ bc56979a-0b38- 2019-07-30 16:\n", + "56c820a9-e83c- 13216 organizations/ 1c755e4b-a65f- 2019-07-30 16:\n", + "6e7ba0be-2171- 36444 organizations/ 9e902f2f-726a- 2019-07-30 16:\n", + "81dc7dae-bebc- 33734 organizations/ 914f5b55-ea69- 2019-07-30 16:\n", + "8c25c65d-506d- 6293 organizations/ 0d59845d-5c75- 2019-07-30 16:\n", + "f35b5a91-38cb- 83564 organizations/ 3cf229ee-dc09- 2019-07-30 16:\n", + "f97ea212-5794- 227965 organizations/ 10ee4617-a63f- 2019-07-30 16:\n", + " (Total: 7)" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ext" + ] + }, { "cell_type": "code", "execution_count": 21, @@ -483,35 +708,35 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Finding untracking files...\n", "Deleting...\n", - "Done\n" + " Deleted: 0 S3 objects; 0 failed.\n" ] } ], "source": [ - "ext.clean_filepaths()" + "ext.clean_blobs()" ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "['dj/file-demo/organizations/logos/bcm.png',\n", + " 'dj/file-demo/organizations/logos/datajoint.png']" ] }, - "execution_count": 24, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -522,7 +747,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -544,7 +769,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -561,7 +786,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -631,23 +856,31 @@ " AK\n", "AlaskaAL\n", "AlabamaAR\n", - "Arkansas \n", + "ArkansasAZ\n", + "ArizonaCA\n", + "CaliforniaCO\n", + "ColoradoCT\n", + "Connecticut \n", " \n", "

...

\n", "

Total: 50

\n", " " ], "text/plain": [ - "*state_code state \n", - "+------------+ +----------+\n", - "AK Alaska \n", - "AL Alabama \n", - "AR Arkansas \n", + "*state_code state \n", + "+------------+ +------------+\n", + "AK Alaska \n", + "AL Alabama \n", + "AR Arkansas \n", + "AZ Arizona \n", + "CA California \n", + "CO Colorado \n", + "CT Connecticut \n", " ...\n", " (Total: 50)" ] }, - "execution_count": 28, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -658,7 +891,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -685,7 +918,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -751,7 +984,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -778,8 +1011,10 @@ }, { "cell_type": "code", - "execution_count": 32, - "metadata": {}, + "execution_count": 30, + "metadata": { + "scrolled": true + }, "outputs": [ { "name": "stdout", @@ -842,13 +1077,144 @@ "StateFlower().populate()" ] }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "\n", + "Logo\n", + "\n", + "\n", + "Logo\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "StateFlower\n", + "\n", + "\n", + "StateFlower\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Organization\n", + "\n", + "\n", + "Organization\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Organization->Logo\n", + "\n", + "\n", + "\n", + "\n", + "StateBird\n", + "\n", + "\n", + "StateBird\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "State\n", + "\n", + "\n", + "State\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "State->StateFlower\n", + "\n", + "\n", + "\n", + "\n", + "State->StateBird\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.Diagram(schema)" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "dj.Diagram(schema)" + "@schema\n", + "class Table(dj.Manual):\n", + " definition = \"\"\"\n", + " table : int\n", + " ---\n", + " legs : int\n", + " area : float\n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Table.insert1((3, 8, 1002.4))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Table.proj(..., load = 'area/legs').fetch('legs', 'load', as_dict=True)" ] }, { @@ -875,7 +1241,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.3" } }, "nbformat": 4, diff --git a/notebooks/Improvements.ipynb b/notebooks/Improvements.ipynb index f39470b..d3106ab 100644 --- a/notebooks/Improvements.ipynb +++ b/notebooks/Improvements.ipynb @@ -9,17 +9,57 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Connecting dimitri@datajoint.internationalbrainlab.org:3306\n" - ] + "data": { + "text/plain": [ + "['ibl_acquisition',\n", + " 'ibl_action',\n", + " 'ibl_alyxraw',\n", + " 'ibl_analyses_behavior',\n", + " 'ibl_behavior',\n", + " 'ibl_data',\n", + " 'ibl_dj_acquisition',\n", + " 'ibl_dj_action',\n", + " 'ibl_dj_alyxraw',\n", + " 'ibl_dj_analyses_behavior',\n", + " 'ibl_dj_behavior',\n", + " 'ibl_dj_data',\n", + " 'ibl_dj_ingest_acquisition',\n", + " 'ibl_dj_ingest_action',\n", + " 'ibl_dj_ingest_data',\n", + " 'ibl_dj_ingest_reference',\n", + " 'ibl_dj_ingest_subject',\n", + " 'ibl_dj_plotting_behavior',\n", + " 'ibl_dj_reference',\n", + " 'ibl_dj_subject',\n", + " 'ibl_ephys',\n", + " 'ibl_ingest_acquisition',\n", + " 'ibl_ingest_action',\n", + " 'ibl_ingest_data',\n", + " 'ibl_ingest_reference',\n", + " 'ibl_ingest_subject',\n", + " 'ibl_plotting_behavior',\n", + " 'ibl_reference',\n", + " 'ibl_subject']" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" } ], + "source": [ + "dj.list_schemas()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], "source": [ "import datajoint as dj\n", "reference = dj.create_virtual_module('reference', 'ibl_dj_reference')\n", @@ -30,6 +70,562 @@ "behavior = dj.create_virtual_module('behavior', 'ibl_dj_behavior')" ] }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "\n", + "176\n", + "\n", + "176\n", + "\n", + "\n", + "\n", + "subject.Litter\n", + "\n", + "\n", + "subject.Litter\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "176->subject.Litter\n", + "\n", + "\n", + "\n", + "\n", + "178\n", + "\n", + "178\n", + "\n", + "\n", + "\n", + "subject.Subject\n", + "\n", + "\n", + "subject.Subject\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "178->subject.Subject\n", + "\n", + "\n", + "\n", + "\n", + "171\n", + "\n", + "171\n", + "\n", + "\n", + "\n", + "subject.BreedingPair\n", + "\n", + "\n", + "subject.BreedingPair\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "171->subject.BreedingPair\n", + "\n", + "\n", + "\n", + "\n", + "172\n", + "\n", + "172\n", + "\n", + "\n", + "\n", + "172->subject.BreedingPair\n", + "\n", + "\n", + "\n", + "\n", + "177\n", + "\n", + "177\n", + "\n", + "\n", + "\n", + "177->subject.Subject\n", + "\n", + "\n", + "\n", + "\n", + "173\n", + "\n", + "173\n", + "\n", + "\n", + "\n", + "173->subject.BreedingPair\n", + "\n", + "\n", + "\n", + "\n", + "174\n", + "\n", + "174\n", + "\n", + "\n", + "\n", + "174->subject.BreedingPair\n", + "\n", + "\n", + "\n", + "\n", + "subject.SubjectUser\n", + "\n", + "\n", + "subject.SubjectUser\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->172\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->173\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->174\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.SubjectUser\n", + "\n", + "\n", + "\n", + "\n", + "subject.Death\n", + "\n", + "\n", + "subject.Death\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.Death\n", + "\n", + "\n", + "\n", + "\n", + "subject.SubjectProject\n", + "\n", + "\n", + "subject.SubjectProject\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.SubjectProject\n", + "\n", + "\n", + "\n", + "\n", + "subject.Weaning\n", + "\n", + "\n", + "subject.Weaning\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.Weaning\n", + "\n", + "\n", + "\n", + "\n", + "subject.Caging\n", + "\n", + "\n", + "subject.Caging\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.Caging\n", + "\n", + "\n", + "\n", + "\n", + "subject.UserHistory\n", + "\n", + "\n", + "subject.UserHistory\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.UserHistory\n", + "\n", + "\n", + "\n", + "\n", + "subject.GenotypeTest\n", + "\n", + "\n", + "subject.GenotypeTest\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.GenotypeTest\n", + "\n", + "\n", + "\n", + "\n", + "subject.SubjectLab\n", + "\n", + "\n", + "subject.SubjectLab\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.SubjectLab\n", + "\n", + "\n", + "\n", + "\n", + "subject.Implant\n", + "\n", + "\n", + "subject.Implant\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.Implant\n", + "\n", + "\n", + "\n", + "\n", + "subject.LitterSubject\n", + "\n", + "\n", + "subject.LitterSubject\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.LitterSubject\n", + "\n", + "\n", + "\n", + "\n", + "subject.Zygosity\n", + "\n", + "\n", + "subject.Zygosity\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Subject->subject.Zygosity\n", + "\n", + "\n", + "\n", + "\n", + "subject.Species\n", + "\n", + "\n", + "subject.Species\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Line\n", + "\n", + "\n", + "subject.Line\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Species->subject.Line\n", + "\n", + "\n", + "\n", + "\n", + "subject.LineAllele\n", + "\n", + "\n", + "subject.LineAllele\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Sequence\n", + "\n", + "\n", + "subject.Sequence\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.AlleleSequence\n", + "\n", + "\n", + "subject.AlleleSequence\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Sequence->subject.AlleleSequence\n", + "\n", + "\n", + "\n", + "\n", + "subject.Sequence->subject.GenotypeTest\n", + "\n", + "\n", + "\n", + "\n", + "subject.Strain\n", + "\n", + "\n", + "subject.Strain\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Strain->subject.Line\n", + "\n", + "\n", + "\n", + "\n", + "subject.BreedingPair->subject.Litter\n", + "\n", + "\n", + "\n", + "\n", + "subject.Allele\n", + "\n", + "\n", + "subject.Allele\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Allele->subject.LineAllele\n", + "\n", + "\n", + "\n", + "\n", + "subject.Allele->subject.AlleleSequence\n", + "\n", + "\n", + "\n", + "\n", + "subject.Allele->subject.Zygosity\n", + "\n", + "\n", + "\n", + "\n", + "subject.Litter->subject.LitterSubject\n", + "\n", + "\n", + "\n", + "\n", + "subject.Source\n", + "\n", + "\n", + "subject.Source\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "subject.Source->178\n", + "\n", + "\n", + "\n", + "\n", + "subject.Source->subject.Allele\n", + "\n", + "\n", + "\n", + "\n", + "subject.Line->176\n", + "\n", + "\n", + "\n", + "\n", + "subject.Line->171\n", + "\n", + "\n", + "\n", + "\n", + "subject.Line->177\n", + "\n", + "\n", + "\n", + "\n", + "subject.Line->subject.LineAllele\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.Diagram(subject)" + ] + }, { "cell_type": "markdown", "metadata": {}, diff --git a/notebooks/Question-002.ipynb b/notebooks/Question-002.ipynb index 36f7a00..14c68a6 100644 --- a/notebooks/Question-002.ipynb +++ b/notebooks/Question-002.ipynb @@ -31,7 +31,7 @@ "\n", "and access all its tables.\n", "\n", - "However, that schema was defined in a notebook. DataJoint provides a method for importing a virtual module. " + "However, that schema was defined in a notebook. DataJoint provides function `dj.create_virtual_module` to mimic importing a virtual module by reconstructing it from the tables in the database." ] }, { diff --git a/notebooks/UUID.ipynb b/notebooks/UUID.ipynb index 75a6918..e7a3baf 100644 --- a/notebooks/UUID.ipynb +++ b/notebooks/UUID.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -24,18 +24,48 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function uuid1 in module uuid:\n", + "\n", + "uuid1(node=None, clock_seq=None)\n", + " Generate a UUID from a host ID, sequence number, and the current time.\n", + " If 'node' is not given, getnode() is used to obtain the hardware\n", + " address. If 'clock_seq' is given, it is used as the sequence number;\n", + " otherwise a random 14-bit sequence number is chosen.\n", + "\n" + ] + } + ], "source": [ "help(uuid.uuid1)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[UUID('8d552590-b940-11e9-9213-7470fdf23ef1'),\n", + " UUID('8d552591-b940-11e9-9213-7470fdf23ef1'),\n", + " UUID('8d552592-b940-11e9-9213-7470fdf23ef1'),\n", + " UUID('8d552593-b940-11e9-9213-7470fdf23ef1'),\n", + " UUID('8d552594-b940-11e9-9213-7470fdf23ef1')]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# use the current hardware address and time\n", "[uuid.uuid1() for _ in range(5)]" @@ -43,9 +73,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[UUID('8d552595-b940-11e9-9213-7470fdf23ef1'),\n", + " UUID('8d552596-b940-11e9-9213-7470fdf23ef1'),\n", + " UUID('8d552597-b940-11e9-9213-7470fdf23ef1'),\n", + " UUID('8d552598-b940-11e9-9213-7470fdf23ef1'),\n", + " UUID('8d552599-b940-11e9-9213-7470fdf23ef1')]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# use the current hardware address and time\n", "[uuid.uuid1() for _ in range(5)]" @@ -53,9 +98,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[UUID('8e345e3a-b940-11e9-8001-7470fdf23ef1'),\n", + " UUID('8e346188-b940-11e9-8001-7470fdf23ef1'),\n", + " UUID('8e34629c-b940-11e9-8001-7470fdf23ef1'),\n", + " UUID('8e346370-b940-11e9-8001-7470fdf23ef1'),\n", + " UUID('8e346438-b940-11e9-8001-7470fdf23ef1')]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# use fixed values\n", "[uuid.uuid1(None, 1) for _ in range(5)]" @@ -63,27 +123,66 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function uuid3 in module uuid:\n", + "\n", + "uuid3(namespace, name)\n", + " Generate a UUID from the MD5 hash of a namespace UUID and a name.\n", + "\n" + ] + } + ], "source": [ "help(uuid.uuid3)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function uuid5 in module uuid:\n", + "\n", + "uuid5(namespace, name)\n", + " Generate a UUID from the SHA-1 hash of a namespace UUID and a name.\n", + "\n" + ] + } + ], "source": [ "help(uuid.uuid5)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(UUID('345b4a08-7955-5b86-8646-f0826799afe9'),\n", + " UUID('b5804c3f-57b1-54e3-8176-3b45aa443a97'),\n", + " UUID('58571fff-c6bd-583f-88ac-ef0b8ff2981f'),\n", + " UUID('b5804c3f-57b1-54e3-8176-3b45aa443a97'),\n", + " UUID('6340129b-3a59-5354-aec6-5df769ae2ce7'))" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "top = uuid.UUID('00000000-0000-0000-0000-000000000000')\n", "topic = uuid.uuid5(top, 'Neuroscience')\n", @@ -99,36 +198,93 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "UUID('3d9d9035-dec3-5fc8-b66c-38cd8537acbe')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "uuid.uuid5(subject4, 'study'*1000000)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on function uuid4 in module uuid:\n", + "\n", + "uuid4()\n", + " Generate a random UUID.\n", + "\n" + ] + } + ], "source": [ "help(uuid.uuid4)" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[UUID('7b946ea0-17f1-48b6-83d3-f78a9b6a7c94'),\n", + " UUID('baa17a66-c87e-4961-9ffc-a3ac43d113dd'),\n", + " UUID('8d12a6dc-8a63-4f89-9d3a-6d7a1b8b2611'),\n", + " UUID('27c51ddf-e360-491d-8dd5-15238967b2b3'),\n", + " UUID('79cd953d-8e26-45ca-85a3-ae458387a65e'),\n", + " UUID('8500f53d-2026-4891-913a-62ffced44c81'),\n", + " UUID('d2648a4c-25e8-4094-a3bc-c9b22d35b466'),\n", + " UUID('dee8b4c3-a9e0-4820-bffc-a8c8504c6203'),\n", + " UUID('6cda1007-b98f-42f5-83ce-e96b9a6d5b42'),\n", + " UUID('56b73a84-7097-4af1-82d7-02665833d222'),\n", + " UUID('7d3c579c-76c9-4f7e-97bf-71b6001eb164'),\n", + " UUID('b93f2f0d-938b-4ff6-bca0-6998557e742d')]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "[uuid.uuid4() for _ in range(12)]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(UUID('5b1e88c5-b46d-4f47-afaf-08b6d5d585eb'),\n", + " '5b1e88c5-b46d-4f47-afaf-08b6d5d585eb')" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "a = uuid.uuid4()\n", "s = str(a)\n", @@ -137,27 +293,61 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "UUID('5b1e88c5-b46d-4f47-afaf-08b6d5d585eb')" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "a" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(UUID('5b1e88c5-b46d-4f47-afaf-08b6d5d585eb'),\n", + " '5b1e88c5-b46d-4f47-afaf-08b6d5d585eb')" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "a, s" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "UUID('5b1e88c5-b46d-4f47-afaf-08b6d5d585eb')" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "uuid.UUID(s)" ] @@ -171,9 +361,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'0.12.dev5'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "import datajoint as dj\n", "dj.__version__" @@ -181,16 +382,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dimitri@localhost:3306\n" + ] + } + ], "source": [ "schema = dj.schema('dimitri_uuid')" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -203,6 +412,26 @@ " \"\"\"" ] }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "message_id : uuid # internal message id\n", + "---\n", + "message_body : varchar(1000) \n", + "\n" + ] + } + ], + "source": [ + "Message.describe();" + ] + }, { "cell_type": "code", "execution_count": null, @@ -386,7 +615,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.7.3" } }, "nbformat": 4, From 833cc6ed8e6df37b9932f728b5f52e33ee174cc3 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Fri, 20 Sep 2019 15:49:52 -0500 Subject: [PATCH 09/11] add the Attachment notebook --- notebooks/Attachments.ipynb | 2758 +++++++++++++++++++++++++++++++++++ notebooks/Filepaths.ipynb | 1159 ++++++++++++--- 2 files changed, 3676 insertions(+), 241 deletions(-) create mode 100644 notebooks/Attachments.ipynb diff --git a/notebooks/Attachments.ipynb b/notebooks/Attachments.ipynb new file mode 100644 index 0000000..1791d60 --- /dev/null +++ b/notebooks/Attachments.ipynb @@ -0,0 +1,2758 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Attachnments and configurable blobs (new or revised in datajoint 0.12.0)\n", + "This notebooks demonstrates the storaage and retrieval of complex datatypes (blobs) and file attachments in DataJoint.\n", + "\n", + "A **blob** refers to an attribute in a table that can store complex data structures such as numeric arrays.\n", + "\n", + "An **attachment** refers to an attribute that can store an entire file with its filename, etc.\n", + "\n", + "Both blobs and attachments can be stored directly in the tables of the relational database or in configurable external \"stores\" such as network-attached storage servers or object storage systems such [Amazon S3](https://aws.amazon.com/s3/) and [Minio](https://min.io/).\n", + "\n", + "Many of these features existing in prior releases of datajoint but have been substantially expanded in version 0.12.0." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "from IPython import display\n", + "from matplotlib import pyplot as plt\n", + "import os\n", + "import imageio\n", + "import requests\n", + "from ipywidgets import Image\n", + "import ipywidgets\n", + "import numpy as np\n", + "\n", + "import datajoint as dj" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0.12.dev7'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure stores\n", + "The following is a configuration defining two external stores. This should only be done once for all users and the configuration file must be saved and provided to all users.\n", + "\n", + "The first store is named `\"shared\"` and is hosted on an S3 endpoint. \n", + "\n", + "The second store is named `\"local\"` and it uses the local path `./dj-store`.\n", + "\n", + "Now these repositories can be used for blobs and attachments." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "## Storage configuration\n", + "\n", + "# set up stores\n", + "dj.config['stores'] = {\n", + " 'shared': dict(\n", + " protocol='s3',\n", + " endpoint='localhost:9000',\n", + " access_key='datajoint',\n", + " secret_key='datajoint',\n", + " bucket='datajoint-demo', \n", + " location=''\n", + " ), \n", + " 'local': { # store in files\n", + " 'protocol': 'file',\n", + " 'location': os.path.abspath('./dj-store')\n", + " }}" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dimitri@localhost:3306\n" + ] + } + ], + "source": [ + "# create a schema for this demo\n", + "schema = dj.schema('test_attach')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Proceed to delete entire schema `test_attach`? [yes, No]: yes\n" + ] + } + ], + "source": [ + "schema.drop() # drop if exists to create anew" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# create a schema for this demo\n", + "schema = dj.schema('test_attach')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Minimal example of blobs and configurable blobs\n", + "Let's declear the table Test with blobs and attachments stored intrnally and externally." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Test(dj.Manual):\n", + " definition = \"\"\"\n", + " # Test blob and attachments\n", + " id : int\n", + " ---\n", + " b0 : longblob # a python object stored internally in the table\n", + " b1 : blob@shared # a python object stored on S3\n", + " b2 : blob@local # a python object store on the file system\n", + " a0 : attach # a file attachment stored internally in the table\n", + " a1 : attach@shared # a file attachment stored on s3\n", + " a2 : attach@local # a file attachment stored on the file system\n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Create three numpy arrays as save them in different files\n", + "q0, q1, q2 = np.random.randn(3,4), np.random.randn(7), np.random.randn(2, 3, 4)\n", + "f0, f1, f2 = './outfile0.npy', './outfile1.npy', './outfile2.npy'\n", + "np.save(f0, q0)\n", + "np.save(f1, q1)\n", + "np.save(f2, q2)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "About to delete:\n", + "Nothing to delete\n" + ] + } + ], + "source": [ + "Test.delete()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# insert the blobs and the attachments into the table\n", + "Test.insert1(dict(id=1, b0=q0, b1=q1, b2=q2, a0=f0, a1=f1, a2=f2))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " Test blob and attachments\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

id

\n", + " \n", + "
\n", + "

b0

\n", + " a python object stored internally in the table\n", + "
\n", + "

b1

\n", + " a python object stored on S3\n", + "
\n", + "

b2

\n", + " a python object store on the file system\n", + "
\n", + "

a0

\n", + " a file attachment stored internally in the table\n", + "
\n", + "

a1

\n", + " a file attachment stored on s3\n", + "
\n", + "

a2

\n", + " a file attachment stored on the file system\n", + "
1=BLOB==BLOB==BLOB==BLOB==BLOB==BLOB=
\n", + " \n", + "

Total: 1

\n", + " " + ], + "text/plain": [ + "*id b0 b1 b2 a0 a1 a2 \n", + "+----+ +--------+ +--------+ +--------+ +--------+ +--------+ +--------+\n", + "1 =BLOB= =BLOB= =BLOB= =BLOB= =BLOB= =BLOB= \n", + " (Total: 1)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Test()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# delete the attached files\n", + "os.remove(f0)\n", + "os.remove(f1)\n", + "os.remove(f2)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# now fetch them and verify that they retrieved correctly\n", + "result = Test.fetch(as_dict=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-0.03270063, 1.48132664, -0.47460454, 0.53584166],\n", + " [-0.54839705, 0.06459001, -0.12448809, 0.1326574 ],\n", + " [ 0.68458856, 0.36013697, 0.00544484, 0.30176943]])" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result[0]['b0']" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[-0.03270063, 1.48132664, -0.47460454, 0.53584166],\n", + " [-0.54839705, 0.06459001, -0.12448809, 0.1326574 ],\n", + " [ 0.68458856, 0.36013697, 0.00544484, 0.30176943]])" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "q0" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.array_equal(q0, result[0]['b0'])" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "PosixPath('outfile1.npy')" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result[0]['a1']" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1.24891915, -1.16716244, -0.55109167, -0.45738901, -0.68241222,\n", + " -0.23278837, 1.23499246])" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "np.load(result[0]['a1'])" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 1.24891915, -1.16716244, -0.55109167, -0.45738901, -0.68241222,\n", + " -0.23278837, 1.23499246])" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "q1" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "External file tables for schema `test_attach`:\n", + " \"shared\" s3:\"\n", + " \"local\" file:/home/dimitri/dev/db-programming-with-datajoint/notebooks/dj-store\"" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
1faa3094-d718-075c-9c94-f1a6c0505c55320outfile2.npyNoneNone2019-09-20 20:35:22
784db39e-7622-9539-a896-d3afb854250c237NoneNoneNone2019-09-20 20:35:22
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +------+ +------------+ +----------+ +------------+ +------------+\n", + "1faa3094-d718- 320 outfile2.npy None None 2019-09-20 20:\n", + "784db39e-7622- 237 None None None 2019-09-20 20:\n", + " (Total: 2)" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['local']" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
013ac743-ddf5-afc8-bf7d-40fcf3754758184outfile1.npyNoneNone2019-09-20 20:35:22
90dccd2e-fb2a-02c5-8556-f494b7a4ac5785NoneNoneNone2019-09-20 20:35:22
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +------+ +------------+ +----------+ +------------+ +------------+\n", + "013ac743-ddf5- 184 outfile1.npy None None 2019-09-20 20:\n", + "90dccd2e-fb2a- 85 None None None 2019-09-20 20:\n", + " (Total: 2)" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared']" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(UUID('1faa3094-d718-075c-9c94-f1a6c0505c55'),\n", + " PurePosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/dj-store/test_attach/1f/aa/1faa3094d718075c9c94f1a6c0505c55.outfile2.npy')),\n", + " (UUID('784db39e-7622-9539-a896-d3afb854250c'),\n", + " PurePosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/dj-store/test_attach/78/4d/784db39e76229539a896d3afb854250c'))]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['local'].fetch_external_paths()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(UUID('013ac743-ddf5-afc8-bf7d-40fcf3754758'),\n", + " PurePosixPath('test_attach/01/3a/013ac743ddf5afc8bf7d40fcf3754758.outfile1.npy')),\n", + " (UUID('90dccd2e-fb2a-02c5-8556-f494b7a4ac57'),\n", + " PurePosixPath('test_attach/90/dc/90dccd2efb2a02c58556f494b7a4ac57'))]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].fetch_external_paths()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
013ac743-ddf5-afc8-bf7d-40fcf3754758184outfile1.npyNoneNone2019-09-20 20:35:22
90dccd2e-fb2a-02c5-8556-f494b7a4ac5785NoneNoneNone2019-09-20 20:35:22
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +------+ +------------+ +----------+ +------------+ +------------+\n", + "013ac743-ddf5- 184 outfile1.npy None None 2019-09-20 20:\n", + "90dccd2e-fb2a- 85 None None None 2019-09-20 20:\n", + " (Total: 2)" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].used()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
1faa3094-d718-075c-9c94-f1a6c0505c55320outfile2.npyNoneNone2019-09-20 20:35:22
784db39e-7622-9539-a896-d3afb854250c237NoneNoneNone2019-09-20 20:35:22
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +------+ +------------+ +----------+ +------------+ +------------+\n", + "1faa3094-d718- 320 outfile2.npy None None 2019-09-20 20:\n", + "784db39e-7622- 237 None None None 2019-09-20 20:\n", + " (Total: 2)" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['local'].used()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
\n", + " \n", + "

Total: 0

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------+ +------+ +------------+ +----------+ +------------+ +-----------+\n", + "\n", + " (Total: 0)" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].unused()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "About to delete:\n", + "`test_attach`.`test`: 1 items\n", + "Proceed? [yes, No]: yes\n", + "Committed.\n" + ] + } + ], + "source": [ + "Test.delete()" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
013ac743-ddf5-afc8-bf7d-40fcf3754758184outfile1.npyNoneNone2019-09-20 20:35:22
90dccd2e-fb2a-02c5-8556-f494b7a4ac5785NoneNoneNone2019-09-20 20:35:22
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +------+ +------------+ +----------+ +------------+ +------------+\n", + "013ac743-ddf5- 184 outfile1.npy None None 2019-09-20 20:\n", + "90dccd2e-fb2a- 85 None None None 2019-09-20 20:\n", + " (Total: 2)" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared']" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 2/2 [00:00<00:00, 74.11it/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].delete() # deleted" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "0it [00:00, ?it/s]\n", + "100%|██████████| 2/2 [00:00<00:00, 70.79it/s]\n" + ] + } + ], + "source": [ + "# cleanup\n", + "for s in schema.external.values():\n", + " s.delete()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Lookup of images on the web\n", + "We create a lookup table, WebImage to point to some images available on the web" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class WebImage(dj.Lookup):\n", + " definition = \"\"\"\n", + " # A reference to a web image\n", + " image_number : int\n", + " ---\n", + " image_name : varchar(30)\n", + " image_description : varchar(1024)\n", + " image_url : varchar(1024)\n", + " \n", + " unique index(image_name)\n", + " \"\"\"\n", + " contents = [\n", + " (0, \"pyramidal\", \n", + " \n", + " 'Coronal section containing the chronically imaged pyramidal neuron \"dow\" '\\\n", + " '(visualized by green GFP) does not stain for GABA (visualized by antibody staining in red). '\\\n", + " 'Confocal image stack, overlay of GFP and GABA channels. Scale bar: 100 um',\n", + " \n", + " \"https://upload.wikimedia.org/wikipedia/commons/d/dc/PLoSBiol4.e126.Fig6fNeuron.jpg\"\n", + " ),\n", + " (1, \"striatal\", \n", + " \n", + " \"Mouse spiny striatal projection neuron expressing a transgenic fluorescent protein \"\\\n", + " \"(colored yellow) delivered by a recombinant virus (AAV). \"\\\n", + " \"The striatal interneuron are stainerd in green for the neurokinin-1 receptor.\",\n", + " \n", + " \"https://upload.wikimedia.org/wikipedia/commons/e/e8/Striatal_neuron_in_an_interneuron_cage.jpg\"\n", + " )\n", + " ]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Preview the images directly from the web" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5924873873724ae1b142b8776b46bbd0", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Image(value=b'https://upload.wikimedia.org/wikipedia/commons/d/dc/PLoSBiol4.e126.Fig6fNeuron.jpg', format='url…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Image.from_url((WebImage & 'image_number=0').fetch1('image_url'))" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "530a6e0f4ad041528d738808d5642088", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Image(value=b'https://upload.wikimedia.org/wikipedia/commons/e/e8/Striatal_neuron_in_an_interneuron_cage.jpg',…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "Image.from_url((WebImage & 'image_number=1').fetch1('image_url'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define a table with attachments\n", + "Now we can use the stores to define attachment attributes in the form `attribute_name : attach@store # comment` where the store is either `@local` or `@shared` as defined above.\n", + "\n", + "Let's define the table `OriginalFile` to automatically download and attach files from `WebImage` and stores the attachments in the shared store." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class OriginalFile(dj.Imported):\n", + " definition = \"\"\"\n", + " -> WebImage\n", + " ---\n", + " image_file : attach@shared\n", + " \"\"\"\n", + " \n", + " def make(self, key):\n", + " # get the URL\n", + " url = (WebImage & key).fetch1('image_url')\n", + " \n", + " # download the file from the web\n", + " local_file = os.path.join(os.path.abspath('.'), url.split('/')[-1])\n", + " with open(local_file, 'wb') as f:\n", + " f.write(requests.get(url).content)\n", + " \n", + " # attach the file\n", + " self.insert1(dict(key, image_file=local_file))\n", + " \n", + " # delete the downloaded file\n", + " os.remove(local_file)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "\n", + "WebImage\n", + "\n", + "\n", + "WebImage\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OriginalFile\n", + "\n", + "\n", + "OriginalFile\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "WebImage->OriginalFile\n", + "\n", + "\n", + "\n", + "\n", + "Test\n", + "\n", + "\n", + "Test\n", + "\n", + "\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dj.Diagram(schema)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [], + "source": [ + "# perform the download\n", + "OriginalFile.populate()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "
\n", + "

image_number

\n", + " \n", + "
\n", + "

image_file

\n", + " \n", + "
0=BLOB=
1=BLOB=
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*image_number image_file\n", + "+------------+ +--------+\n", + "0 =BLOB= \n", + "1 =BLOB= \n", + " (Total: 2)" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "OriginalFile()" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9b85398bbd984658ae143dee9ad6d0ca", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Image(value=b'\\xff\\xd8\\xff\\xe0\\x00\\x10JFIF\\x00\\x01\\x01\\x01\\x00`\\x00`\\x00\\x00\\xff\\xdb\\x00C\\x00\\x01\\x01\\x01\\x01\\…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# preview downloaded attachment\n", + "file = (OriginalFile & 'image_number=1').fetch1('image_file')\n", + "Image.from_file(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [], + "source": [ + "os.remove(file)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Extract images into blobs\n", + "Now let's define another class that extracts imags from attached files and stores as blobs in the local store." + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [], + "source": [ + "# Declare a table with a configurable blob\n", + "@schema\n", + "class Slide(dj.Computed):\n", + " definition = \"\"\"\n", + " -> OriginalFile\n", + " ---\n", + " image_array : blob@local # array in specified store\n", + " \"\"\"\n", + " \n", + " def make(self, key):\n", + " # get the attached file\n", + " file = (OriginalFile & key).fetch1('image_file')\n", + " \n", + " # save image data\n", + " self.insert1(dict(key, image_array=imageio.imread(file)))\n", + " \n", + " # remove the downloaded file\n", + " os.remove(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "Slide.populate()" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "
\n", + "

image_number

\n", + " \n", + "
\n", + "

image_array

\n", + " array in specified store\n", + "
1=BLOB=
0=BLOB=
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*image_number image_arra\n", + "+------------+ +--------+\n", + "1 =BLOB= \n", + "0 =BLOB= \n", + " (Total: 2)" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Slide()" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "External file tables for schema `test_attach`:\n", + " \"shared\" s3:\"\n", + " \"local\" file:/home/dimitri/dev/db-programming-with-datajoint/notebooks/dj-store\"" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
403b8717-6c83-fa52-d381-e1371e61e4ac1324311NoneNoneNone2019-09-20 20:35:59
cbc9f232-6abd-6863-c449-9cb82a11e47a1707130NoneNoneNone2019-09-20 20:35:59
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +---------+ +------------+ +----------+ +------------+ +------------+\n", + "403b8717-6c83- 1324311 None None None 2019-09-20 20:\n", + "cbc9f232-6abd- 1707130 None None None 2019-09-20 20:\n", + " (Total: 2)" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['local']" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Plot image form a blob\n", + "plt.imshow((Slide & 'image_number=0').fetch1('image_array'));" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Caching\n", + "By default, the data from blobs and attachments are retrieved from remote stores with every fetch command. \n", + "For repeated queries, a cache folder may be specified to improve performance and reduce cost of operations.\n", + "After the first fetch of a given blob or attachment, it will be read from the cache. " + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [], + "source": [ + "# configure the cache\n", + "dj.config['cache'] = './dj-cache'" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [], + "source": [ + "# clear the cache for the timing test\n", + "import shutil\n", + "if os.path.isdir(dj.config['cache']):\n", + " shutil.rmtree(dj.config['cache'])" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "17.7 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit -n1 -r1\n", + "\n", + "# first time no cache\n", + "files = OriginalFile.fetch('image_file')" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "11.4 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit -n1 -r1\n", + "\n", + "# now with cache\n", + "files = OriginalFile.fetch('image_file')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Deleting\n", + "Deleting from tables using external storage is just as simple and transaction-safe as with all other kinds of attributes. Simply use the `delete` method:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "External file tables for schema `test_attach`:\n", + " \"shared\" s3:\"\n", + " \"local\" file:/home/dimitri/dev/db-programming-with-datajoint/notebooks/dj-store\"" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
00bffedc-d5c2-f928-f0d5-4d31fe01311d806133PLoSBiol4.e126.Fig6fNeuron.jpgNoneNone2019-09-20 20:35:53
81c1c2d3-3c08-66ed-1d64-c96376539195895051Striatal_neuron_in_an_interneuron_cage.jpgNoneNone2019-09-20 20:35:53
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +--------+ +------------+ +----------+ +------------+ +------------+\n", + "00bffedc-d5c2- 806133 PLoSBiol4.e126 None None 2019-09-20 20:\n", + "81c1c2d3-3c08- 895051 Striatal_neuro None None 2019-09-20 20:\n", + " (Total: 2)" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared']" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
\n", + " \n", + "

Total: 0

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------+ +------+ +------------+ +----------+ +------------+ +-----------+\n", + "\n", + " (Total: 0)" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].unused()" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "About to delete:\n", + "`test_attach`.`__slide`: 1 items\n", + "`test_attach`.`_original_file`: 1 items\n", + "`test_attach`.`#web_image`: 1 items\n", + "Proceed? [yes, No]: yes\n", + "Committed.\n" + ] + } + ], + "source": [ + "(WebImage & 'image_number=0').delete()" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
00bffedc-d5c2-f928-f0d5-4d31fe01311d806133PLoSBiol4.e126.Fig6fNeuron.jpgNoneNone2019-09-20 20:35:53
\n", + " \n", + "

Total: 1

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +--------+ +------------+ +----------+ +------------+ +------------+\n", + "00bffedc-d5c2- 806133 PLoSBiol4.e126 None None 2019-09-20 20:\n", + " (Total: 1)" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].unused()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Deleting" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For the sake of performance, deleting from the data tables does not remove the data from external storage. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `delete` method of the external table deletes its **unused** entries and their corresponding external files." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "External file tables for schema `test_attach`:\n", + " \"shared\" s3:\"\n", + " \"local\" file:/home/dimitri/dev/db-programming-with-datajoint/notebooks/dj-store\"" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You may cleanup the external table using its `delete` method. It is a transaction-safe operation and can be performed at any time." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 1/1 [00:00<00:00, 47.74it/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['local'].delete()" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 1/1 [00:00<00:00, 66.55it/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].delete()" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "0it [00:00, ?it/s]\n", + "0it [00:00, ?it/s]\n" + ] + } + ], + "source": [ + "for s in schema.external.values():\n", + " s.delete()" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
81c1c2d3-3c08-66ed-1d64-c96376539195895051Striatal_neuron_in_an_interneuron_cage.jpgNoneNone2019-09-20 20:35:53
\n", + " \n", + "

Total: 1

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +--------+ +------------+ +----------+ +------------+ +------------+\n", + "81c1c2d3-3c08- 895051 Striatal_neuro None None 2019-09-20 20:\n", + " (Total: 1)" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].used()" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
\n", + " \n", + "

Total: 0

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------+ +------+ +------------+ +----------+ +------------+ +-----------+\n", + "\n", + " (Total: 0)" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['shared'].unused()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/Filepaths.ipynb b/notebooks/Filepaths.ipynb index 633f669..e8d20e9 100644 --- a/notebooks/Filepaths.ipynb +++ b/notebooks/Filepaths.ipynb @@ -15,25 +15,17 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "schema.drop()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dimitri@localhost:3306\n" + ] + } + ], "source": [ "schema = dj.schema('dimitri_filepath')" ] @@ -44,36 +36,15 @@ "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "['dimitri_alter',\n", - " 'dimitri_attach',\n", - " 'dimitri_blob',\n", - " 'dimitri_blobs',\n", - " 'dimitri_filepath',\n", - " 'dimitri_nphoton',\n", - " 'dimitri_nwb',\n", - " 'dimitri_schema',\n", - " 'dimitri_test',\n", - " 'dimitri_university',\n", - " 'dimitri_uuid',\n", - " 'test_attach',\n", - " 'test_filepath',\n", - " 'test_mikkel',\n", - " 'test_orders',\n", - " 'test_parse',\n", - " 'test_question001',\n", - " 'test_question002',\n", - " 'university']" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "Proceed to delete entire schema `dimitri_filepath`? [yes, No]: yes\n" + ] } ], "source": [ - "dj.list_schemas()" + "schema.drop() # drop schema to start demo from scratch" ] }, { @@ -81,6 +52,15 @@ "execution_count": 5, "metadata": {}, "outputs": [], + "source": [ + "schema = dj.schema('dimitri_filepath')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], "source": [ "## Storage configuration\n", "\n", @@ -93,7 +73,7 @@ " access_key='datajoint',\n", " secret_key='datajoint',\n", " bucket='datajoint-demo', \n", - " location='dj/file-demo'), \n", + " location='code-clinic'), \n", " }" ] }, @@ -106,7 +86,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -123,13 +103,13 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "9edffe4b13144cd9af50cc58ce890e66", + "model_id": "a7a51c63e3bb4d5d96ebb26f02c5c984", "version_major": 2, "version_minor": 0 }, @@ -147,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -163,7 +143,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -256,7 +236,7 @@ " (Total: 7)" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -267,7 +247,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -297,7 +277,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -320,7 +300,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -413,7 +393,7 @@ " (Total: 7)" ] }, - "execution_count": 12, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -424,29 +404,29 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[{'organization': 'pydata',\n", - " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pydata.png'},\n", + " 'logo_image': PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pydata.png')},\n", " {'organization': 'utah',\n", - " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/utah.png'},\n", + " 'logo_image': PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/utah.png')},\n", " {'organization': 'datajoint',\n", - " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png'},\n", + " 'logo_image': PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png')},\n", " {'organization': 'ucsd',\n", - " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/ucsd.png'},\n", + " 'logo_image': PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/ucsd.png')},\n", " {'organization': 'pni',\n", - " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pni.png'},\n", + " 'logo_image': PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pni.png')},\n", " {'organization': 'python',\n", - " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/python.png'},\n", + " 'logo_image': PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/python.png')},\n", " {'organization': 'bcm',\n", - " 'logo_image': '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png'}]" + " 'logo_image': PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png')}]" ] }, - "execution_count": 13, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -457,7 +437,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -468,7 +448,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -477,23 +457,23 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "array(['/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pydata.png',\n", - " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/utah.png',\n", - " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png',\n", - " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/ucsd.png',\n", - " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pni.png',\n", - " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/python.png',\n", - " '/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png'],\n", + "array([PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pydata.png'),\n", + " PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/utah.png'),\n", + " PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/datajoint.png'),\n", + " PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/ucsd.png'),\n", + " PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/pni.png'),\n", + " PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/python.png'),\n", + " PosixPath('/home/dimitri/dev/db-programming-with-datajoint/notebooks/stage/organizations/logos/bcm.png')],\n", " dtype=object)" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -504,13 +484,13 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "3598ff4bf5fa401fb985cad84ec5d05e", + "model_id": "5cea364859fc47c79ca2f1e79dfb2f2c", "version_major": 2, "version_minor": 0 }, @@ -528,7 +508,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -548,7 +528,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -557,7 +537,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -624,8 +604,11 @@ "

size

\n", " size of object in bytes\n", "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", "

filepath

\n", - " relative filepath used in the filepath datatype\n", + " relative filepath or attachment filename\n", "
\n", "

contents_hash

\n", " used for the filepath datatype\n", @@ -635,52 +618,59 @@ "
\n", " 3fd4b79b-9fdd-95c0-4074-68614d97f7e1\n", "162\n", + "None\n", "organizations/logos/pydata.png\n", "bc56979a-0b38-1a79-1dd5-9713198a87fb\n", - "2019-07-30 16:50:4056c820a9-e83c-02c9-8e76-7ba908192588\n", + "2019-09-20 20:29:4056c820a9-e83c-02c9-8e76-7ba908192588\n", "13216\n", + "None\n", "organizations/logos/utah.png\n", "1c755e4b-a65f-5576-352e-729f0c5987da\n", - "2019-07-30 16:50:416e7ba0be-2171-a2ab-163e-ff12b0943e8e\n", + "2019-09-20 20:29:406e7ba0be-2171-a2ab-163e-ff12b0943e8e\n", "36444\n", + "None\n", "organizations/logos/datajoint.png\n", "9e902f2f-726a-2da5-0a24-ee3b97892f8a\n", - "2019-07-30 16:50:3881dc7dae-bebc-6d38-b891-c48eee8e340a\n", + "2019-09-20 20:29:3981dc7dae-bebc-6d38-b891-c48eee8e340a\n", "33734\n", + "None\n", "organizations/logos/ucsd.png\n", "914f5b55-ea69-7489-d45b-031bec3ecaa5\n", - "2019-07-30 16:50:408c25c65d-506d-f382-0e36-88e1f6057ea3\n", + "2019-09-20 20:29:408c25c65d-506d-f382-0e36-88e1f6057ea3\n", "6293\n", + "None\n", "organizations/logos/pni.png\n", "0d59845d-5c75-24f8-20c8-9637517ed6a7\n", - "2019-07-30 16:50:39f35b5a91-38cb-bc7f-ef17-b2ce94bb0131\n", + "2019-09-20 20:29:39f35b5a91-38cb-bc7f-ef17-b2ce94bb0131\n", "83564\n", + "None\n", "organizations/logos/python.png\n", "3cf229ee-dc09-2549-277e-8859aad2fca5\n", - "2019-07-30 16:50:40f97ea212-5794-926a-d852-deffc0f10bba\n", + "2019-09-20 20:29:40f97ea212-5794-926a-d852-deffc0f10bba\n", "227965\n", + "None\n", "organizations/logos/bcm.png\n", "10ee4617-a63f-61ba-2807-35a266a9f488\n", - "2019-07-30 16:50:38 \n", + "2019-09-20 20:29:39 \n", " \n", " \n", "

Total: 7

\n", " " ], "text/plain": [ - "*hash size filepath contents_hash timestamp \n", - "+------------+ +--------+ +------------+ +------------+ +------------+\n", - "3fd4b79b-9fdd- 162 organizations/ bc56979a-0b38- 2019-07-30 16:\n", - "56c820a9-e83c- 13216 organizations/ 1c755e4b-a65f- 2019-07-30 16:\n", - "6e7ba0be-2171- 36444 organizations/ 9e902f2f-726a- 2019-07-30 16:\n", - "81dc7dae-bebc- 33734 organizations/ 914f5b55-ea69- 2019-07-30 16:\n", - "8c25c65d-506d- 6293 organizations/ 0d59845d-5c75- 2019-07-30 16:\n", - "f35b5a91-38cb- 83564 organizations/ 3cf229ee-dc09- 2019-07-30 16:\n", - "f97ea212-5794- 227965 organizations/ 10ee4617-a63f- 2019-07-30 16:\n", + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +--------+ +------------+ +------------+ +------------+ +------------+\n", + "3fd4b79b-9fdd- 162 None organizations/ bc56979a-0b38- 2019-09-20 20:\n", + "56c820a9-e83c- 13216 None organizations/ 1c755e4b-a65f- 2019-09-20 20:\n", + "6e7ba0be-2171- 36444 None organizations/ 9e902f2f-726a- 2019-09-20 20:\n", + "81dc7dae-bebc- 33734 None organizations/ 914f5b55-ea69- 2019-09-20 20:\n", + "8c25c65d-506d- 6293 None organizations/ 0d59845d-5c75- 2019-09-20 20:\n", + "f35b5a91-38cb- 83564 None organizations/ 3cf229ee-dc09- 2019-09-20 20:\n", + "f97ea212-5794- 227965 None organizations/ 10ee4617-a63f- 2019-09-20 20:\n", " (Total: 7)" ] }, - "execution_count": 20, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -689,39 +679,118 @@ "ext" ] }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Deleted 2 items\n" - ] - } - ], - "source": [ - "ext.delete()" - ] - }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Deleting...\n", - " Deleted: 0 S3 objects; 0 failed.\n" - ] + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
6e7ba0be-2171-a2ab-163e-ff12b0943e8e36444Noneorganizations/logos/datajoint.png9e902f2f-726a-2da5-0a24-ee3b97892f8a2019-09-20 20:29:39
f97ea212-5794-926a-d852-deffc0f10bba227965Noneorganizations/logos/bcm.png10ee4617-a63f-61ba-2807-35a266a9f4882019-09-20 20:29:39
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +--------+ +------------+ +------------+ +------------+ +------------+\n", + "6e7ba0be-2171- 36444 None organizations/ 9e902f2f-726a- 2019-09-20 20:\n", + "f97ea212-5794- 227965 None organizations/ 10ee4617-a63f- 2019-09-20 20:\n", + " (Total: 2)" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "ext.clean_blobs()" + "ext.unused()" ] }, { @@ -732,8 +801,10 @@ { "data": { "text/plain": [ - "['dj/file-demo/organizations/logos/bcm.png',\n", - " 'dj/file-demo/organizations/logos/datajoint.png']" + "[(UUID('6e7ba0be-2171-a2ab-163e-ff12b0943e8e'),\n", + " PurePosixPath('code-clinic/organizations/logos/datajoint.png')),\n", + " (UUID('f97ea212-5794-926a-d852-deffc0f10bba'),\n", + " PurePosixPath('code-clinic/organizations/logos/bcm.png'))]" ] }, "execution_count": 23, @@ -742,52 +813,40 @@ } ], "source": [ - "list(ext.get_untracked_filepaths())" + "ext.unused().fetch_external_paths()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 2/2 [00:00<00:00, 67.15it/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "states = dict(\n", - " AL='Alabama', AK='Alaska', AZ='Arizona', AR='Arkansas',\n", - " CA='California', CO='Colorado', CT='Connecticut', DE='Delaware',\n", - " FL='Florida', GA='Georgia', HI='Hawaii', ID='Idaho', \n", - " IL='Illinois', IN='Indiana', IA='Iowa', KS='Kansas',\n", - " KY='Kentucky', LA='Louisiana', ME='Maine', MD='Maryland',\n", - " MA='Massachusetts', MI='Michigan', MN='Minnesota', MS='Mississippi',\n", - " MO='Missouri', MT='Montana', NE='Nebraska', NV='Nevada',\n", - " NH='New Hampshire', NJ='New Jersey', NM='New Mexico', NY='New York',\n", - " NC='North Carolina', ND='North Dakota', OH='Ohio', OK='Oklahoma',\n", - " OR='Oregon', PA='Pennsylvania', RI='Rhode Island', SC='South Carlina',\n", - " SD='South Dakota', TN='Tennessee', TX='Texas', UT='Utah',\n", - " VT='Vermont', VA='Virginia', WA='Washington', WV='West Virginia', \n", - " WI='Wisconsin', WY='Wyoming')" + "ext.delete()" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, - "outputs": [], - "source": [ - "@schema\n", - "class State(dj.Lookup):\n", - " definition = \"\"\"\n", - " # United States\n", - " state_code : char(2)\n", - " ---\n", - " state : varchar(20)\n", - " \"\"\"\n", - " contents = states.items()" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, "outputs": [ { "data": { @@ -843,23 +902,165 @@ " }\n", " \n", " \n", - " United States\n", + " external storage tracking\n", "
\n", " \n", " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + " \n", + "
\n", - "

state_code

\n", - " \n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", "
\n", - "

state

\n", - " \n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", "
AKAlaska
ALAlabama
ARArkansas
AZArizona
CACalifornia
COColorado
CT
\n", + " \n", + "

Total: 0

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------+ +------+ +------------+ +----------+ +------------+ +-----------+\n", + "\n", + " (Total: 0)" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ext.unused()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "states = dict(\n", + " AL='Alabama', AK='Alaska', AZ='Arizona', AR='Arkansas',\n", + " CA='California', CO='Colorado', CT='Connecticut', DE='Delaware',\n", + " FL='Florida', GA='Georgia', HI='Hawaii', ID='Idaho', \n", + " IL='Illinois', IN='Indiana', IA='Iowa', KS='Kansas',\n", + " KY='Kentucky', LA='Louisiana', ME='Maine', MD='Maryland',\n", + " MA='Massachusetts', MI='Michigan', MN='Minnesota', MS='Mississippi',\n", + " MO='Missouri', MT='Montana', NE='Nebraska', NV='Nevada',\n", + " NH='New Hampshire', NJ='New Jersey', NM='New Mexico', NY='New York',\n", + " NC='North Carolina', ND='North Dakota', OH='Ohio', OK='Oklahoma',\n", + " OR='Oregon', PA='Pennsylvania', RI='Rhode Island', SC='South Carlina',\n", + " SD='South Dakota', TN='Tennessee', TX='Texas', UT='Utah',\n", + " VT='Vermont', VA='Virginia', WA='Washington', WV='West Virginia', \n", + " WI='Wisconsin', WY='Wyoming')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class State(dj.Lookup):\n", + " definition = \"\"\"\n", + " # United States\n", + " state_code : char(2)\n", + " ---\n", + " state : varchar(20)\n", + " \"\"\"\n", + " contents = states.items()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " United States\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", "
\n", + "

state_code

\n", + " \n", + "
\n", + "

state

\n", + " \n", + "
AKAlaska
ALAlabama
ARArkansas
AZArizona
CACalifornia
COColorado
CTConnecticut
\n", "

...

\n", @@ -880,7 +1081,7 @@ " (Total: 50)" ] }, - "execution_count": 26, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -891,7 +1092,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -918,7 +1119,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -984,7 +1185,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -1011,7 +1212,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 32, "metadata": { "scrolled": true }, @@ -1079,102 +1280,102 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ - "\n", + "\n", "\n", "%3\n", - "\n", - "\n", - "\n", - "Logo\n", - "\n", - "\n", - "Logo\n", - "\n", - "\n", - "\n", + "\n", "\n", - "\n", + "\n", "StateFlower\n", - "\n", - "\n", - "StateFlower\n", + "\n", + "StateFlower\n", "\n", "\n", "\n", - "\n", - "\n", - "Organization\n", - "\n", + "\n", + "State\n", + "\n", - "\n", - "Organization\n", + "\n", + "State\n", "\n", "\n", "\n", - "\n", + "\n", "\n", - "Organization->Logo\n", - "\n", + "State->StateFlower\n", + "\n", "\n", "\n", - "\n", + "\n", "StateBird\n", - "\n", - "\n", - "StateBird\n", + "\n", + "StateBird\n", "\n", "\n", "\n", - "\n", - "\n", - "State\n", - "\n", + "\n", + "State->StateBird\n", + "\n", + "\n", + "\n", + "\n", + "Organization\n", + "\n", - "\n", - "State\n", + "\n", + "Organization\n", "\n", "\n", "\n", - "\n", - "\n", - "State->StateFlower\n", - "\n", + "\n", + "\n", + "Logo\n", + "\n", + "\n", + "Logo\n", + "\n", "\n", - "\n", + "\n", + "\n", "\n", - "State->StateBird\n", - "\n", + "Organization->Logo\n", + "\n", "\n", "\n", "" ], "text/plain": [ - "" + "" ] }, - "execution_count": 31, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -1185,36 +1386,512 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "External file tables for schema `dimitri_filepath`:\n", + " \"remote\" s3:code-clinic\"" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "@schema\n", - "class Table(dj.Manual):\n", - " definition = \"\"\"\n", - " table : int\n", - " ---\n", - " legs : int\n", - " area : float\n", - " \"\"\"" + "schema.external" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
01d9c579-f923-81d1-8f35-c7fddbf171f4417Nonestates/flowers/maine.jpg980488b3-8709-9958-e741-77e8b22e6aed2019-09-20 20:30:36
01f19f6d-e7d3-b718-8b1b-8122a211697325735Nonestates/birds/texas.jpg0c1f52a6-8cef-1534-3b5c-bb03f52f6b782019-09-20 20:30:27
02621cc5-6215-f043-2297-1844393d603b416Nonestates/flowers/iowa.jpg2e98d103-ff1a-387f-f84b-a4653fe69b292019-09-20 20:30:34
0315aac9-440c-ed4f-f6d1-1581547212be25142Nonestates/birds/indiana.jpg511d9eac-52a7-7a76-b60a-ed3131c088742019-09-20 20:30:23
0427f842-2a48-a302-af48-fc2973d8fbbe25142Nonestates/birds/kentucky.jpg511d9eac-52a7-7a76-b60a-ed3131c088742019-09-20 20:30:24
056a7914-856d-3f8e-7880-6432ab313d58425Nonestates/flowers/west virginia.jpgbe37e4f6-93d3-3aa1-f326-b4c765c106482019-09-20 20:30:39
09adf4ec-d9c7-ee18-868e-e577a9ea8731422Nonestates/birds/south dakota.jpgf6df925d-149e-9629-4d2d-82a6786fd92b2019-09-20 20:30:27
\n", + "

...

\n", + "

Total: 105

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------------+ +-------+ +------------+ +------------+ +------------+ +------------+\n", + "01d9c579-f923- 417 None states/flowers 980488b3-8709- 2019-09-20 20:\n", + "01f19f6d-e7d3- 25735 None states/birds/t 0c1f52a6-8cef- 2019-09-20 20:\n", + "02621cc5-6215- 416 None states/flowers 2e98d103-ff1a- 2019-09-20 20:\n", + "0315aac9-440c- 25142 None states/birds/i 511d9eac-52a7- 2019-09-20 20:\n", + "0427f842-2a48- 25142 None states/birds/k 511d9eac-52a7- 2019-09-20 20:\n", + "056a7914-856d- 425 None states/flowers be37e4f6-93d3- 2019-09-20 20:\n", + "09adf4ec-d9c7- 422 None states/birds/s f6df925d-149e- 2019-09-20 20:\n", + " ...\n", + " (Total: 105)" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "Table.insert1((3, 8, 1002.4))" + "schema.external['remote']" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(UUID('01d9c579-f923-81d1-8f35-c7fddbf171f4'),\n", + " PurePosixPath('code-clinic/states/flowers/maine.jpg')),\n", + " (UUID('01f19f6d-e7d3-b718-8b1b-8122a2116973'),\n", + " PurePosixPath('code-clinic/states/birds/texas.jpg')),\n", + " (UUID('02621cc5-6215-f043-2297-1844393d603b'),\n", + " PurePosixPath('code-clinic/states/flowers/iowa.jpg')),\n", + " (UUID('0315aac9-440c-ed4f-f6d1-1581547212be'),\n", + " PurePosixPath('code-clinic/states/birds/indiana.jpg')),\n", + " (UUID('0427f842-2a48-a302-af48-fc2973d8fbbe'),\n", + " PurePosixPath('code-clinic/states/birds/kentucky.jpg')),\n", + " (UUID('056a7914-856d-3f8e-7880-6432ab313d58'),\n", + " PurePosixPath('code-clinic/states/flowers/west virginia.jpg')),\n", + " (UUID('09adf4ec-d9c7-ee18-868e-e577a9ea8731'),\n", + " PurePosixPath('code-clinic/states/birds/south dakota.jpg')),\n", + " (UUID('0e1c29e6-6bf1-5d23-1e06-cc9ee05d79d9'),\n", + " PurePosixPath('code-clinic/states/birds/north dakota.jpg')),\n", + " (UUID('114da747-fee3-a47d-e90b-be2e1cc0bfe0'),\n", + " PurePosixPath('code-clinic/states/flowers/washington.jpg')),\n", + " (UUID('17f485a8-eca3-d740-9100-7bc6caae9faa'),\n", + " PurePosixPath('code-clinic/states/birds/new york.jpg')),\n", + " (UUID('184bd7b2-9885-89dd-7da6-e425fbe535f2'),\n", + " PurePosixPath('code-clinic/states/flowers/missouri.jpg')),\n", + " (UUID('1b0a55dd-344c-e06e-7bfe-7e0f5ca5c188'),\n", + " PurePosixPath('code-clinic/states/birds/minnesota.jpg')),\n", + " (UUID('1e9a63ab-7dd3-9735-2e4c-d03b679709c1'),\n", + " PurePosixPath('code-clinic/states/birds/michigan.jpg')),\n", + " (UUID('22647fa9-bcd3-417b-797a-2c98ea6904aa'),\n", + " PurePosixPath('code-clinic/states/flowers/virginia.jpg')),\n", + " (UUID('246b2008-8f03-31e0-6d34-db8ccfc39494'),\n", + " PurePosixPath('code-clinic/states/birds/maine.jpg')),\n", + " (UUID('24fcd4ca-a9eb-ca77-b1bd-9430c6fbb51b'),\n", + " PurePosixPath('code-clinic/states/flowers/california.jpg')),\n", + " (UUID('277679c0-f7b2-f54c-1d3b-f19e8b0d15f9'),\n", + " PurePosixPath('code-clinic/states/flowers/massachusetts.jpg')),\n", + " (UUID('2a34aa82-edb9-5064-b773-0b6d9e51cdb0'),\n", + " PurePosixPath('code-clinic/states/flowers/north carolina.jpg')),\n", + " (UUID('2ba8d00e-c4f2-b86e-6870-c4a51395e6f8'),\n", + " PurePosixPath('code-clinic/states/flowers/new hampshire.jpg')),\n", + " (UUID('2bbb860f-df7b-cd91-aa42-9e97cbc1dc9d'),\n", + " PurePosixPath('code-clinic/states/flowers/north dakota.jpg')),\n", + " (UUID('2ed31b79-217e-63b9-6ef0-91fcd16eb054'),\n", + " PurePosixPath('code-clinic/states/flowers/michigan.jpg')),\n", + " (UUID('325725fb-7ec0-23b5-d460-1e026b36dcdf'),\n", + " PurePosixPath('code-clinic/states/birds/ohio.jpg')),\n", + " (UUID('3347e424-aa9c-b85f-a8d6-50fd93c8b264'),\n", + " PurePosixPath('code-clinic/states/flowers/florida.jpg')),\n", + " (UUID('33b1c381-4cad-6437-42a8-5bcbd1751e6c'),\n", + " PurePosixPath('code-clinic/states/birds/vermont.jpg')),\n", + " (UUID('33ed18b0-d09f-334b-62ef-0f83151db34b'),\n", + " PurePosixPath('code-clinic/states/flowers/wisconsin.jpg')),\n", + " (UUID('341157e6-d8db-703a-1953-7e422666a173'),\n", + " PurePosixPath('code-clinic/states/birds/massachusetts.jpg')),\n", + " (UUID('39a1a53e-a326-0bde-5500-c17024e7703f'),\n", + " PurePosixPath('code-clinic/states/flowers/mississippi.jpg')),\n", + " (UUID('3c7d8b20-e576-a604-97ec-f2ca692651dd'),\n", + " PurePosixPath('code-clinic/states/birds/illinois.jpg')),\n", + " (UUID('3e382bd8-1d25-6f10-a88a-4b7fa69fcfc1'),\n", + " PurePosixPath('code-clinic/states/birds/alabama.jpg')),\n", + " (UUID('3fd4b79b-9fdd-95c0-4074-68614d97f7e1'),\n", + " PurePosixPath('code-clinic/organizations/logos/pydata.png')),\n", + " (UUID('428ccfc3-837d-fb1f-8f71-fa2b1fbd5fe5'),\n", + " PurePosixPath('code-clinic/states/flowers/vermont.jpg')),\n", + " (UUID('438a5157-bf38-c247-bf71-0a6633eb3fb6'),\n", + " PurePosixPath('code-clinic/states/birds/oregon.jpg')),\n", + " (UUID('459d0e6e-be54-3802-2be9-bbb4d0c21e7c'),\n", + " PurePosixPath('code-clinic/states/flowers/colorado.jpg')),\n", + " (UUID('45b1800a-7a87-3ad7-70d6-2aad9ad8981b'),\n", + " PurePosixPath('code-clinic/states/birds/north carolina.jpg')),\n", + " (UUID('4914c53d-ab3f-d6b3-59c7-790657984757'),\n", + " PurePosixPath('code-clinic/states/birds/wisconsin.jpg')),\n", + " (UUID('4a398dae-9893-d31b-867c-c64def9ac541'),\n", + " PurePosixPath('code-clinic/states/flowers/texas.jpg')),\n", + " (UUID('4ad20148-4af0-97b1-65e3-47b73f988a00'),\n", + " PurePosixPath('code-clinic/states/birds/washington.jpg')),\n", + " (UUID('51f95d0b-7528-1840-1b4f-ffbe04286f9a'),\n", + " PurePosixPath('code-clinic/states/flowers/nebraska.jpg')),\n", + " (UUID('56107d48-aa13-e4eb-773d-7b33c2909fe9'),\n", + " PurePosixPath('code-clinic/states/birds/virginia.jpg')),\n", + " (UUID('56c820a9-e83c-02c9-8e76-7ba908192588'),\n", + " PurePosixPath('code-clinic/organizations/logos/utah.png')),\n", + " (UUID('587ad22e-14a9-b41d-fbb7-13d85702fbd6'),\n", + " PurePosixPath('code-clinic/states/flowers/kansas.jpg')),\n", + " (UUID('5ded7dea-8fa2-2450-419d-7fb24ee581e9'),\n", + " PurePosixPath('code-clinic/states/flowers/south carlina.jpg')),\n", + " (UUID('61a1dd90-eda9-69de-a7a0-cdbd1627fed1'),\n", + " PurePosixPath('code-clinic/states/flowers/utah.jpg')),\n", + " (UUID('628be6e1-f489-2521-7eca-f8690d410019'),\n", + " PurePosixPath('code-clinic/states/birds/iowa.jpg')),\n", + " (UUID('6338bb2d-1000-a5ae-3ff2-27deb02171f1'),\n", + " PurePosixPath('code-clinic/states/birds/mississippi.jpg')),\n", + " (UUID('637e4577-8098-45d2-ac8f-5d95919a9ccf'),\n", + " PurePosixPath('code-clinic/states/birds/connecticut.jpg')),\n", + " (UUID('6b1cd553-5072-0702-98e7-fbc89022bccb'),\n", + " PurePosixPath('code-clinic/states/flowers/georgia.jpg')),\n", + " (UUID('6f8df4a5-06f0-5f89-c08d-42b97c192ef4'),\n", + " PurePosixPath('code-clinic/states/birds/alaska.jpg')),\n", + " (UUID('6fa95b8c-46e1-ca63-6610-142ab0bcb4af'),\n", + " PurePosixPath('code-clinic/states/birds/louisiana.jpg')),\n", + " (UUID('6fb24649-c923-678d-67e1-331b42a2a024'),\n", + " PurePosixPath('code-clinic/states/birds/oklahoma.jpg')),\n", + " (UUID('7328d3ca-ccda-bbf5-2d56-1da4b58aaba0'),\n", + " PurePosixPath('code-clinic/states/birds/wyoming.jpg')),\n", + " (UUID('75482e52-f840-adc2-0a36-4a50c777bab5'),\n", + " PurePosixPath('code-clinic/states/birds/new jersey.jpg')),\n", + " (UUID('7718d696-e868-e61e-fb8c-c2e9236f45a6'),\n", + " PurePosixPath('code-clinic/states/birds/nevada.jpg')),\n", + " (UUID('7811a892-4744-15ec-ea51-a3b6562c4396'),\n", + " PurePosixPath('code-clinic/states/flowers/alaska.jpg')),\n", + " (UUID('79b941dd-4fbc-a80b-b20e-db91c29b2c40'),\n", + " PurePosixPath('code-clinic/states/flowers/indiana.jpg')),\n", + " (UUID('7e5ade5c-f149-1b0d-b4cd-2a1afa4affc2'),\n", + " PurePosixPath('code-clinic/states/flowers/delaware.jpg')),\n", + " (UUID('7f21244c-8204-20a6-cc87-2dc5a622132c'),\n", + " PurePosixPath('code-clinic/states/flowers/wyoming.jpg')),\n", + " (UUID('7fdc33b3-c7cd-ce42-b662-63796b41656f'),\n", + " PurePosixPath('code-clinic/states/birds/montana.jpg')),\n", + " (UUID('80514116-f2d3-f82a-f911-a8d3a0244305'),\n", + " PurePosixPath('code-clinic/states/birds/utah.jpg')),\n", + " (UUID('806c070a-5bf9-42ff-8174-df2b8b850800'),\n", + " PurePosixPath('code-clinic/states/birds/arizona.jpg')),\n", + " (UUID('8120cada-e54c-a91b-a978-b0aee4c92b82'),\n", + " PurePosixPath('code-clinic/states/flowers/connecticut.jpg')),\n", + " (UUID('81dc7dae-bebc-6d38-b891-c48eee8e340a'),\n", + " PurePosixPath('code-clinic/organizations/logos/ucsd.png')),\n", + " (UUID('86bbbf4b-fa19-6aaa-66bc-321584f267b0'),\n", + " PurePosixPath('code-clinic/states/birds/hawaii.jpg')),\n", + " (UUID('870b42da-bae7-1d04-6b71-14d3c20c8db3'),\n", + " PurePosixPath('code-clinic/states/flowers/oregon.jpg')),\n", + " (UUID('88aeea31-58c4-786e-9741-0318b2a91ea0'),\n", + " PurePosixPath('code-clinic/states/birds/georgia.jpg')),\n", + " (UUID('8c25c65d-506d-f382-0e36-88e1f6057ea3'),\n", + " PurePosixPath('code-clinic/organizations/logos/pni.png')),\n", + " (UUID('8ecc5fb1-2de7-405d-e753-17707a8efb6a'),\n", + " PurePosixPath('code-clinic/states/birds/colorado.jpg')),\n", + " (UUID('932b2892-f641-77c1-4bd6-29ab4a5435dc'),\n", + " PurePosixPath('code-clinic/states/flowers/oklahoma.jpg')),\n", + " (UUID('9b87e3d4-90a6-1222-c971-f08e5bbf7f35'),\n", + " PurePosixPath('code-clinic/states/birds/florida.jpg')),\n", + " (UUID('9ca7acff-e7fa-6132-aa34-235ff5518644'),\n", + " PurePosixPath('code-clinic/states/flowers/new jersey.jpg')),\n", + " (UUID('9d76c6a9-6806-30f0-c5bf-7c1927e98f17'),\n", + " PurePosixPath('code-clinic/states/birds/arkansas.jpg')),\n", + " (UUID('9d7d448d-d6d0-9518-bdc6-9f85b636c8fc'),\n", + " PurePosixPath('code-clinic/states/birds/delaware.jpg')),\n", + " (UUID('a108e5b1-7a55-063b-95ba-a4adad6c5724'),\n", + " PurePosixPath('code-clinic/states/birds/west virginia.jpg')),\n", + " (UUID('a3ae8749-8636-d957-4037-0cca46084e19'),\n", + " PurePosixPath('code-clinic/states/birds/idaho.jpg')),\n", + " (UUID('a48c55fa-05e8-0928-1976-a3b4bf405115'),\n", + " PurePosixPath('code-clinic/states/flowers/louisiana.jpg')),\n", + " (UUID('a65c4bab-cf70-e4c6-3cc3-ed7e1bcc4e1a'),\n", + " PurePosixPath('code-clinic/states/birds/missouri.jpg')),\n", + " (UUID('a9327cbb-baf1-166a-175a-d4c1da6eb8a6'),\n", + " PurePosixPath('code-clinic/states/flowers/alabama.jpg')),\n", + " (UUID('a9cc8108-1273-dac5-b7c8-db290b6c53cb'),\n", + " PurePosixPath('code-clinic/states/flowers/tennessee.jpg')),\n", + " (UUID('ab5d0504-86a5-bb98-5ebc-b1ebb2cd5a9d'),\n", + " PurePosixPath('code-clinic/states/birds/nebraska.jpg')),\n", + " (UUID('b1349a3d-a02a-2b02-ccf9-2750039d5831'),\n", + " PurePosixPath('code-clinic/states/flowers/kentucky.jpg')),\n", + " (UUID('b6973144-e881-ff72-a5f3-8325351e3068'),\n", + " PurePosixPath('code-clinic/states/birds/tennessee.jpg')),\n", + " (UUID('bd23ff8c-619d-4470-8c19-1b1d4fbe228e'),\n", + " PurePosixPath('code-clinic/states/birds/rhode island.jpg')),\n", + " (UUID('beccafba-60c5-dafa-20dc-432197ea4ad9'),\n", + " PurePosixPath('code-clinic/states/birds/maryland.jpg')),\n", + " (UUID('bf223a8a-f627-72da-5bf5-3bc53e78babd'),\n", + " PurePosixPath('code-clinic/states/flowers/ohio.jpg')),\n", + " (UUID('bf9db2bc-13c7-aa5b-d2ed-80e6a77dc3c7'),\n", + " PurePosixPath('code-clinic/states/flowers/south dakota.jpg')),\n", + " (UUID('bfb01da0-82a6-31de-cfd3-ea3dd79863ad'),\n", + " PurePosixPath('code-clinic/states/birds/new mexico.jpg')),\n", + " (UUID('c172bb0c-434e-ad47-81ce-2d7861eb4dec'),\n", + " PurePosixPath('code-clinic/states/birds/kansas.jpg')),\n", + " (UUID('c2bac2f9-74bb-be06-1f43-9badf662ae42'),\n", + " PurePosixPath('code-clinic/states/flowers/hawaii.jpg')),\n", + " (UUID('c30057d1-8f4f-13aa-6f79-3d88c25f31ad'),\n", + " PurePosixPath('code-clinic/states/birds/pennsylvania.jpg')),\n", + " (UUID('c3d92ad3-be39-8416-f632-6683842428ed'),\n", + " PurePosixPath('code-clinic/states/flowers/rhode island.jpg')),\n", + " (UUID('d2131650-6079-7909-89e0-085cb30f27ea'),\n", + " PurePosixPath('code-clinic/states/flowers/arizona.jpg')),\n", + " (UUID('d2351cc0-2379-882a-a0e0-875574b6a1f2'),\n", + " PurePosixPath('code-clinic/states/birds/california.jpg')),\n", + " (UUID('e114c51c-e671-53ba-bde2-6d1bdaf478f9'),\n", + " PurePosixPath('code-clinic/states/birds/new hampshire.jpg')),\n", + " (UUID('e3afc8d6-3136-5008-ee53-78815b6b7cc3'),\n", + " PurePosixPath('code-clinic/states/flowers/arkansas.jpg')),\n", + " (UUID('eba07400-1c2a-d25d-9b7a-84da614f9ae5'),\n", + " PurePosixPath('code-clinic/states/flowers/maryland.jpg')),\n", + " (UUID('f35b5a91-38cb-bc7f-ef17-b2ce94bb0131'),\n", + " PurePosixPath('code-clinic/organizations/logos/python.png')),\n", + " (UUID('f3d173a2-3998-e56e-3187-d72b9a80e143'),\n", + " PurePosixPath('code-clinic/states/flowers/minnesota.jpg')),\n", + " (UUID('f47f158e-6f86-8863-1999-da771defb285'),\n", + " PurePosixPath('code-clinic/states/flowers/idaho.jpg')),\n", + " (UUID('f48977ed-bb21-506f-3e93-76c6c6abb0cf'),\n", + " PurePosixPath('code-clinic/states/flowers/pennsylvania.jpg')),\n", + " (UUID('f501a5b4-5689-45fb-f062-b33063167bfc'),\n", + " PurePosixPath('code-clinic/states/flowers/new york.jpg')),\n", + " (UUID('f509ca79-2169-19fc-b7bc-37d8a3e3c4c8'),\n", + " PurePosixPath('code-clinic/states/flowers/montana.jpg')),\n", + " (UUID('f78e4d0e-ed71-734f-86d2-7de0e070dc96'),\n", + " PurePosixPath('code-clinic/states/flowers/new mexico.jpg')),\n", + " (UUID('f83d03ce-4e72-7e80-0a49-b0f03479d62c'),\n", + " PurePosixPath('code-clinic/states/flowers/illinois.jpg')),\n", + " (UUID('f96070ba-836b-5f3a-2151-73340ba0b5e0'),\n", + " PurePosixPath('code-clinic/states/birds/south carlina.jpg')),\n", + " (UUID('fd45e697-bdc4-3408-56e0-2709469f6b7f'),\n", + " PurePosixPath('code-clinic/states/flowers/nevada.jpg'))]" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['remote'].fetch_external_paths()" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " external storage tracking\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + "

hash

\n", + " hash of contents (blob), of filename + contents (attach), or relative filepath (filepath)\n", + "
\n", + "

size

\n", + " size of object in bytes\n", + "
\n", + "

attachment_name

\n", + " the filename of an attachment\n", + "
\n", + "

filepath

\n", + " relative filepath or attachment filename\n", + "
\n", + "

contents_hash

\n", + " used for the filepath datatype\n", + "
\n", + "

timestamp

\n", + " automatic timestamp\n", + "
\n", + " \n", + "

Total: 0

\n", + " " + ], + "text/plain": [ + "*hash size attachment_nam filepath contents_hash timestamp \n", + "+------+ +------+ +------------+ +----------+ +------------+ +-----------+\n", + "\n", + " (Total: 0)" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "schema.external['remote'].unused()" + ] + }, + { + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "Table.proj(..., load = 'area/legs').fetch('legs', 'load', as_dict=True)" + "## Remaining issues:\n", + "\n", + "* Re-inserting the same filepath twice with different contents throws and error. This is fixed by deleting the unused external table entries.\n", + "* Users may need the option to fetch only the paths or object handles without downloading the files. Fetch option or config?\n", + "* Dropping the schema leaves orphaned externals. However, dropping tables works normally.\n", + "* Insert(query) with externals has not tested." ] }, { From bcb5ce2330ec4b3a5deee37527912db783079de0 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Fri, 12 Mar 2021 21:52:44 -0600 Subject: [PATCH 10/11] add Update1.ipynb to describe the use of Update1. --- notebooks/Adapted-Types-2.ipynb | 28 +- notebooks/Adapted-Types.ipynb | 52 +- .../Getting Started with DataJoint.ipynb | 4781 ++++++++++++----- notebooks/Improvements.ipynb | 2 +- notebooks/Update1.ipynb | 348 ++ 5 files changed, 3960 insertions(+), 1251 deletions(-) create mode 100644 notebooks/Update1.ipynb diff --git a/notebooks/Adapted-Types-2.ipynb b/notebooks/Adapted-Types-2.ipynb index 7bc141b..e436022 100644 --- a/notebooks/Adapted-Types-2.ipynb +++ b/notebooks/Adapted-Types-2.ipynb @@ -39,7 +39,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connecting dimitri@localhost:3306\n" + "Connecting dbadmin@dimitri-proj0.cda95qzjbnvs.us-east-1.rds.amazonaws.com:3306\n" ] } ], @@ -109,23 +109,15 @@ }, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/dimitri/.local/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py:579: MatplotlibDeprecationWarning: \n", - "The iterable function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use np.iterable instead.\n", - " if not cb.iterable(width):\n" + "ename": "NameError", + "evalue": "name 'Connectivity' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\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 2\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmatplotlib\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpyplot\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mConnectivity\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfetch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'conn_graph'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0morder_by\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'conn_id'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mfig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubplots\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msize\u001b[0m \u001b[0;34m,\u001b[0m \u001b[0mfigsize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m15\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\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[0;31mNameError\u001b[0m: name 'Connectivity' is not defined" ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" } ], "source": [ @@ -249,7 +241,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff --git a/notebooks/Adapted-Types.ipynb b/notebooks/Adapted-Types.ipynb index fb8825a..2d6088d 100644 --- a/notebooks/Adapted-Types.ipynb +++ b/notebooks/Adapted-Types.ipynb @@ -23,18 +23,9 @@ "execution_count": 1, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/dimitri/.local/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py:579: MatplotlibDeprecationWarning: \n", - "The iterable function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use np.iterable instead.\n", - " if not cb.iterable(width):\n" - ] - }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -113,7 +104,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Connecting dimitri@localhost:3306\n", + "Connecting dbadmin@dimitri-proj0.cda95qzjbnvs.us-east-1.rds.amazonaws.com:3306\n", "Proceed to delete entire schema `test_graphs`? [yes, No]: yes\n" ] } @@ -129,6 +120,17 @@ "execution_count": 5, "metadata": {}, "outputs": [], + "source": [ + "# The following is necessary in DataJoint version 0.12.* \n", + "# while adapted types are in beta testing.\n", + "dj.errors._switch_adapted_types(True) " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], "source": [ "@schema\n", "class Connectivity(dj.Manual):\n", @@ -141,7 +143,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -169,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -185,23 +187,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/dimitri/.local/lib/python3.7/site-packages/networkx/drawing/nx_pylab.py:579: MatplotlibDeprecationWarning: \n", - "The iterable function was deprecated in Matplotlib 3.1 and will be removed in 3.3. Use np.iterable instead.\n", - " if not cb.iterable(width):\n" - ] - }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -218,15 +211,6 @@ " plt.sca(ax)\n", " nx.draw(g)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Connectivity.insert1()" - ] } ], "metadata": { @@ -245,7 +229,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.8.5" } }, "nbformat": 4, diff --git a/notebooks/Getting Started with DataJoint.ipynb b/notebooks/Getting Started with DataJoint.ipynb index 1d3f470..3f14c44 100644 --- a/notebooks/Getting Started with DataJoint.ipynb +++ b/notebooks/Getting Started with DataJoint.ipynb @@ -25,12 +25,23 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dbadmin@dimitri-proj0.cda95qzjbnvs.us-east-1.rds.amazonaws.com:3306\n", + "Proceed to delete entire schema `university`? [yes, No]: yes\n" + ] + } + ], "source": [ + "schema = dj.schema('university')\n", + "schema.drop()\n", "schema = dj.schema('university')" ] }, @@ -43,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": { "scrolled": false }, @@ -69,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -82,87 +93,86 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
1
\n", + " \n", + " \n", "\n", "\n", "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
1AliceAndersonF
\n", - " \n", - "

Total: 1

\n", - " " + " \n", + " \n", + "

Total: 1

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex \n", @@ -171,7 +181,7 @@ " (Total: 1)" ] }, - "execution_count": 8, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -189,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -198,90 +208,89 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
1
\n", + " \n", + " \n", "\n", "\n", "\n", "\n", "\n", "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
1AliceAndersonF
2BobDylanM
\n", - " \n", - "

Total: 2

\n", - " " + " \n", + " \n", + "

Total: 2

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex \n", @@ -291,7 +300,7 @@ " (Total: 2)" ] }, - "execution_count": 10, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -302,7 +311,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -311,80 +320,79 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
1
\n", + " \n", + " \n", "\n", "\n", "\n", @@ -394,10 +402,10 @@ "\n", "\n", "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
1AliceAndersonF
2CarolLewisF
\n", - " \n", - "

Total: 3

\n", - " " + " \n", + " \n", + "

Total: 3

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex \n", @@ -408,7 +416,7 @@ " (Total: 3)" ] }, - "execution_count": 12, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -426,7 +434,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -440,80 +448,79 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
1
\n", + " \n", + " \n", "\n", "\n", "\n", @@ -532,10 +539,10 @@ "\n", "\n", "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
1AliceAndersonF
2MaxScottM
\n", - " \n", - "

Total: 6

\n", - " " + " \n", + " \n", + "

Total: 6

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex \n", @@ -549,7 +556,7 @@ " (Total: 6)" ] }, - "execution_count": 15, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -567,7 +574,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -581,80 +588,79 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
1
\n", + " \n", + " \n", "\n", "\n", "\n", @@ -682,10 +688,10 @@ "\n", "\n", "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
1AliceAndersonF
2EmmaReedF
\n", - " \n", - "

Total: 9

\n", - " " + " \n", + " \n", + "

Total: 9

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex \n", @@ -702,7 +708,7 @@ " (Total: 9)" ] }, - "execution_count": 18, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -720,7 +726,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -739,7 +745,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -762,7 +768,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -771,7 +777,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -780,231 +786,230 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
\n", - "

date_of_birth

\n", - " \n", - "
\n", - "

home_address

\n", - " mailing street address\n", - "
\n", - "

home_city

\n", - " mailing address\n", - "
\n", - "

home_state

\n", - " US state acronym: e.g. OH\n", - "
\n", - "

home_zip

\n", - " zipcode e.g. 93979-4979\n", - "
\n", - "

home_phone

\n", - " e.g. 414.657.6883x0881\n", - "
0MatthewMilesM1985-11-11279 Joseph Estate Apt. 874MasonstadWA26544830-541-2678
1WillieMayM1995-04-215509 Cross CanyonWest ToddNE512445774925367
2DavidBoone
\n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
\n", + "

date_of_birth

\n", + " \n", + "
\n", + "

home_address

\n", + " mailing street address\n", + "
\n", + "

home_city

\n", + " mailing address\n", + "
\n", + "

home_state

\n", + " US state acronym: e.g. OH\n", + "
\n", + "

home_zip

\n", + " zipcode e.g. 93979-4979\n", + "
\n", + "

home_phone

\n", + " e.g. 414.657.6883x0881\n", + "
0JillianFischerF2000-12-1468627 Rodriguez Center Suite 032East AnthonyWY64660+1-837-213-8181x775
1DanielleMccannF2001-07-10459 Watts Path Suite 309Lake CharlesPA422262367757570
2GabrielAustinM1984-12-1703892 Amy Rapid Apt. 123MaryburyOK21149164.601.2816
3DerekBarrett2002-05-1559647 Bruce GroveNew AlexanderOR48511+1-834-046-2990x923
3GaryAdamsM2000-07-0493045 Pamela PlainNorth BradymouthSD33618519-951-7205x52305
4AlbertDavis1990-12-302740 Henderson Shore Suite 497East KyleVA16432(652)366-4084x188
4AaronDixonM1994-01-15442 Jacob Bypass Apt. 357Lake BrendanCT87296977-228-5606x062
5ErikaPhillips2001-06-1857205 Clark LaneMillermouthAZ90284001-593-504-9751x736
5MackenzieBoyerF1988-03-31911 Tiffany Pike Apt. 570ChristophertownUT56135(889)801-9551x4395
6LucasThomas1988-12-269458 Ashley Stravenue Apt. 044Port MelissalandOH54499669-684-3236
6BradleyWilliamsM2002-01-05810 Williams Dale Apt. 270Port Hannahport1986-03-062067 Gonzalez Summit Suite 002New KaylaAK668751407435812
7NancyFoxF1984-05-1696581 Jackson PortsLake IanmouthLA320465707101635
8DeborahVincent128230458569751
7AnthonyDiazM1990-12-3176723 Anthony CoveSabrinaburyOR42013+1-183-571-0712
8JacquelineColonF2001-01-10237 Elizabeth Pass Suite 178North Jennifer1996-02-2464635 Duncan PlaceSolisburghUT37335+1-696-997-1635x317
9StephanieKoch76301(983)027-5735x055
9NicoleLongF1993-06-128303 Tiffany RestWilsonviewMA14163001-917-947-1447x650
10RobertCooper1986-10-24804 Sarah Rue Suite 661Port KristinamouthND07732568-928-6900x28524
10BrandonGrantM1988-07-142070 Christopher KnollsAndreastadTN13995957-517-9026x7264
11DonnaWilcoxF1990-05-25540 Alexis GreenEast RachaelviewMO329759502795098
\n", - "

...

\n", - "

Total: 900

\n", - " " + "1997-07-31\n", + "245 Christian Well\n", + "Ericside\n", + "ID\n", + "94059\n", + "626711359211\n", + "Kevin\n", + "Walker\n", + "M\n", + "2000-01-16\n", + "12139 Smith Hills\n", + "Coleshire\n", + "OK\n", + "82926\n", + "001-227-524-1444x871 \n", + " \n", + "

...

\n", + "

Total: 300

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex date_of_birth home_address home_city home_state home_zip home_phone \n", "+------------+ +------------+ +-----------+ +-----+ +------------+ +------------+ +------------+ +------------+ +----------+ +------------+\n", - "0 Matthew Miles M 1985-11-11 279 Joseph Est Masonstad WA 26544 830-541-2678 \n", - "1 Willie May M 1995-04-21 5509 Cross Can West Todd NE 51244 5774925367 \n", - "2 David Boone M 1984-12-17 03892 Amy Rapi Marybury OK 21149 164.601.2816 \n", - "3 Derek Barrett M 2000-07-04 93045 Pamela P North Bradymou SD 33618 519-951-7205x5\n", - "4 Albert Davis M 1994-01-15 442 Jacob Bypa Lake Brendan CT 87296 977-228-5606x0\n", - "5 Erika Phillips F 1988-03-31 911 Tiffany Pi Christophertow UT 56135 (889)801-9551x\n", - "6 Lucas Thomas M 2002-01-05 810 Williams D Port Hannahpor AK 66875 1407435812 \n", - "7 Nancy Fox F 1984-05-16 96581 Jackson Lake Ianmouth LA 32046 5707101635 \n", - "8 Deborah Vincent F 2001-01-10 237 Elizabeth North Jennifer UT 37335 +1-696-997-163\n", - "9 Stephanie Koch F 1993-06-12 8303 Tiffany R Wilsonview MA 14163 001-917-947-14\n", - "10 Robert Cooper M 1988-07-14 2070 Christoph Andreastad TN 13995 957-517-9026x7\n", - "11 Donna Wilcox F 1990-05-25 540 Alexis Gre East Rachaelvi MO 32975 9502795098 \n", + "0 Jillian Fischer F 2000-12-14 68627 Rodrigue East Anthony WY 64660 +1-837-213-818\n", + "1 Danielle Mccann F 2001-07-10 459 Watts Path Lake Charles PA 42226 2367757570 \n", + "2 Gabriel Austin M 2002-05-15 59647 Bruce Gr New Alexander OR 48511 +1-834-046-299\n", + "3 Gary Adams M 1990-12-30 2740 Henderson East Kyle VA 16432 (652)366-4084x\n", + "4 Aaron Dixon M 2001-06-18 57205 Clark La Millermouth AZ 90284 001-593-504-97\n", + "5 Mackenzie Boyer F 1988-12-26 9458 Ashley St Port Melissala OH 54499 669-684-3236 \n", + "6 Bradley Williams M 1986-03-06 2067 Gonzalez New Kayla AK 12823 0458569751 \n", + "7 Anthony Diaz M 1990-12-31 76723 Anthony Sabrinabury OR 42013 +1-183-571-071\n", + "8 Jacqueline Colon F 1996-02-24 64635 Duncan P Solisburgh UT 76301 (983)027-5735x\n", + "9 Nicole Long F 1986-10-24 804 Sarah Rue Port Kristinam ND 07732 568-928-6900x2\n", + "10 Brandon Grant M 1997-07-31 245 Christian Ericside ID 94059 6267113592 \n", + "11 Kevin Walker M 2000-01-16 12139 Smith Hi Coleshire OK 82926 001-227-524-14\n", " ...\n", - " (Total: 900)" + " (Total: 300)" ] }, - "execution_count": 26, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -1029,231 +1034,230 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
\n", - "

date_of_birth

\n", - " \n", - "
\n", - "

home_address

\n", - " mailing street address\n", - "
\n", - "

home_city

\n", - " mailing address\n", - "
\n", - "

home_state

\n", - " US state acronym: e.g. OH\n", - "
\n", - "

home_zip

\n", - " zipcode e.g. 93979-4979\n", - "
\n", - "

home_phone

\n", - " e.g. 414.657.6883x0881\n", - "
5ErikaPhillips
\n", + " \n", + " \n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
\n", + "

date_of_birth

\n", + " \n", + "
\n", + "

home_address

\n", + " mailing street address\n", + "
\n", + "

home_city

\n", + " mailing address\n", + "
\n", + "

home_state

\n", + " US state acronym: e.g. OH\n", + "
\n", + "

home_zip

\n", + " zipcode e.g. 93979-4979\n", + "
\n", + "

home_phone

\n", + " e.g. 414.657.6883x0881\n", + "
0JillianFischerF1988-03-31911 Tiffany Pike Apt. 570ChristophertownUT56135(889)801-9551x4395
7NancyFox2000-12-1468627 Rodriguez Center Suite 032East AnthonyWY64660+1-837-213-8181x775
1DanielleMccannF1984-05-1696581 Jackson PortsLake IanmouthLA320465707101635
8DeborahVincent2001-07-10459 Watts Path Suite 309Lake CharlesPA422262367757570
5MackenzieBoyerF2001-01-10237 Elizabeth Pass Suite 178North JenniferUT37335+1-696-997-1635x317
9StephanieKoch1988-12-269458 Ashley Stravenue Apt. 044Port MelissalandOH54499669-684-3236
8JacquelineColonF1993-06-128303 Tiffany RestWilsonviewMA14163001-917-947-1447x650
11DonnaWilcox1996-02-2464635 Duncan PlaceSolisburghUT76301(983)027-5735x055
9NicoleLongF1990-05-25540 Alexis GreenEast RachaelviewMO329759502795098
12DanielleRoth1986-10-24804 Sarah Rue Suite 661Port KristinamouthND07732568-928-6900x28524
13AnnaGoldenF1991-01-04697 Stacy WallSchmidtboroughME35610069.269.5700x454
18ChristineNewman1999-03-09177 Robles PortJamesmouthPA57615862.977.2190
14JessicaRamosF1999-02-2800473 Daniel Freeway Apt. 706New EdwardNM45981287-445-7199x999
19GabrielleCarr1996-08-138318 Kenneth LakesNorth MeganNJ61279(736)120-0323x9695
16HeidiLewisF2000-01-03097 Gina Junction Apt. 926New IsaacCT43134204.887.5818x900
21MonicaWilson1992-03-07810 Wanda Pines Suite 244NicholechesterWA39909001-467-054-8928x041
18DawnPhillipsF1993-11-136255 William DivideWest KathyviewNC65452632.749.3286x370
23KatieBrown2004-08-309205 Margaret Common Apt. 133East JamesCA35646+1-986-030-3766x9704
19BethNielsenF1985-03-299844 Joshua GardenSouth ElizabethMN92773(058)445-6195x48931
26TiffanyJohnson1989-10-1452211 Joseph CoursePort AmandabergWY77459001-289-285-4689
20MikaylaThomasF1997-09-252752 Valerie Passage Apt. 583KennedyshireNC03101255.083.4385
29CatherineCastro2003-10-033104 Riggs Radial Apt. 751MathewsviewTX41272772.655.0583
22KristenWileyF2000-05-08506 Sue FlatRobinsonmouthWY66233+1-820-511-6491
\n", - "

...

\n", - "

Total: 456

\n", - " " + "2003-06-21\n", + "743 Linda Street Suite 948\n", + "Christopherhaven\n", + "WI\n", + "29738\n", + "873-334-4318x117 \n", + " \n", + "

...

\n", + "

Total: 151

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex date_of_birth home_address home_city home_state home_zip home_phone \n", "+------------+ +------------+ +-----------+ +-----+ +------------+ +------------+ +------------+ +------------+ +----------+ +------------+\n", - "5 Erika Phillips F 1988-03-31 911 Tiffany Pi Christophertow UT 56135 (889)801-9551x\n", - "7 Nancy Fox F 1984-05-16 96581 Jackson Lake Ianmouth LA 32046 5707101635 \n", - "8 Deborah Vincent F 2001-01-10 237 Elizabeth North Jennifer UT 37335 +1-696-997-163\n", - "9 Stephanie Koch F 1993-06-12 8303 Tiffany R Wilsonview MA 14163 001-917-947-14\n", - "11 Donna Wilcox F 1990-05-25 540 Alexis Gre East Rachaelvi MO 32975 9502795098 \n", - "12 Danielle Roth F 1991-01-04 697 Stacy Wall Schmidtborough ME 35610 069.269.5700x4\n", - "18 Christine Newman F 1999-02-28 00473 Daniel F New Edward NM 45981 287-445-7199x9\n", - "19 Gabrielle Carr F 2000-01-03 097 Gina Junct New Isaac CT 43134 204.887.5818x9\n", - "21 Monica Wilson F 1993-11-13 6255 William D West Kathyview NC 65452 632.749.3286x3\n", - "23 Katie Brown F 1985-03-29 9844 Joshua Ga South Elizabet MN 92773 (058)445-6195x\n", - "26 Tiffany Johnson F 1997-09-25 2752 Valerie P Kennedyshire NC 03101 255.083.4385 \n", - "29 Catherine Castro F 2000-05-08 506 Sue Flat Robinsonmouth WY 66233 +1-820-511-649\n", + "0 Jillian Fischer F 2000-12-14 68627 Rodrigue East Anthony WY 64660 +1-837-213-818\n", + "1 Danielle Mccann F 2001-07-10 459 Watts Path Lake Charles PA 42226 2367757570 \n", + "5 Mackenzie Boyer F 1988-12-26 9458 Ashley St Port Melissala OH 54499 669-684-3236 \n", + "8 Jacqueline Colon F 1996-02-24 64635 Duncan P Solisburgh UT 76301 (983)027-5735x\n", + "9 Nicole Long F 1986-10-24 804 Sarah Rue Port Kristinam ND 07732 568-928-6900x2\n", + "13 Anna Golden F 1999-03-09 177 Robles Por Jamesmouth PA 57615 862.977.2190 \n", + "14 Jessica Ramos F 1996-08-13 8318 Kenneth L North Megan NJ 61279 (736)120-0323x\n", + "16 Heidi Lewis F 1992-03-07 810 Wanda Pine Nicholechester WA 39909 001-467-054-89\n", + "18 Dawn Phillips F 2004-08-30 9205 Margaret East James CA 35646 +1-986-030-376\n", + "19 Beth Nielsen F 1989-10-14 52211 Joseph C Port Amandaber WY 77459 001-289-285-46\n", + "20 Mikayla Thomas F 2003-10-03 3104 Riggs Rad Mathewsview TX 41272 772.655.0583 \n", + "22 Kristen Wiley F 2003-06-21 743 Linda Stre Christopherhav WI 29738 873-334-4318x1\n", " ...\n", - " (Total: 456)" + " (Total: 151)" ] }, - "execution_count": 27, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -1264,231 +1268,230 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
\n", - "

date_of_birth

\n", - " \n", - "
\n", - "

home_address

\n", - " mailing street address\n", - "
\n", - "

home_city

\n", - " mailing address\n", - "
\n", - "

home_state

\n", - " US state acronym: e.g. OH\n", - "
\n", - "

home_zip

\n", - " zipcode e.g. 93979-4979\n", - "
\n", - "

home_phone

\n", - " e.g. 414.657.6883x0881\n", - "
3DerekBarrettM2000-07-0493045 Pamela PlainNorth BradymouthSD33618519-951-7205x52305
6LucasThomasM2002-01-05810 Williams Dale Apt. 270Port HannahportAK668751407435812
8DeborahVincent
\n", + " \n", + " \n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
\n", + "

date_of_birth

\n", + " \n", + "
\n", + "

home_address

\n", + " mailing street address\n", + "
\n", + "

home_city

\n", + " mailing address\n", + "
\n", + "

home_state

\n", + " US state acronym: e.g. OH\n", + "
\n", + "

home_zip

\n", + " zipcode e.g. 93979-4979\n", + "
\n", + "

home_phone

\n", + " e.g. 414.657.6883x0881\n", + "
0JillianFischerF2001-01-10237 Elizabeth Pass Suite 178North JenniferUT37335+1-696-997-1635x317
13KyleNeal2000-12-1468627 Rodriguez Center Suite 032East AnthonyWY64660+1-837-213-8181x775
1DanielleMccannF2001-07-10459 Watts Path Suite 309Lake CharlesPA422262367757570
2GabrielAustinM2003-07-302079 Hayes DriveSouth Kimberlyhaven2002-05-1559647 Bruce GroveNew AlexanderOR48511+1-834-046-2990x923
4AaronDixonM2001-06-1857205 Clark LaneMillermouthAZ25811294.223.3023
15KyleKirby90284001-593-504-9751x736
11KevinWalkerM2003-01-1855693 Hudson UnderpassSouth AmytownVA27199366.457.5029x8187
19GabrielleCarrF2000-01-03097 Gina Junction Apt. 926New IsaacCT43134204.887.5818x900
22DennisShields2000-01-1612139 Smith HillsColeshireOK82926001-227-524-1444x871
12BradleyJohnsonM2003-08-204385 Jonathan Track Suite 093BenderviewCO53814+1-650-949-3288
27JasonCannon2002-10-2744057 Amber ClubMartinboroughWA965291246630797
17CharlesBurnsM2001-03-12575 Gross CrossingDominguezhavenIL195830305674234
29CatherineCastro2000-03-21374 David ForksWest TylervilleAR66484180-517-6772x0773
18DawnPhillipsF2000-05-08506 Sue FlatRobinsonmouthWY66233+1-820-511-6491
41BradSanchezM2002-04-0415681 Smith GreensWest AlexanderboroughNV82139030.223.4585x6904
42DebbieRocha2004-08-309205 Margaret Common Apt. 133East JamesCA35646+1-986-030-3766x9704
20MikaylaThomasF2001-01-149449 Johnson OvalBryanttownHI20252(298)437-5761x444
45AndrewRiveraM2003-12-2121697 Steve HarborsEast MeredithCT98221257.005.7228
\n", - "

...

\n", - "

Total: 200

\n", - " " + "2003-10-03\n", + "3104 Riggs Radial Apt. 751\n", + "Mathewsview\n", + "TX\n", + "41272\n", + "772.655.058322\n", + "Kristen\n", + "Wiley\n", + "F\n", + "2003-06-21\n", + "743 Linda Street Suite 948\n", + "Christopherhaven\n", + "WI\n", + "29738\n", + "873-334-4318x11725\n", + "Dr.\n", + "Ashley\n", + "F\n", + "2005-03-16\n", + "1004 Fuller Route Suite 401\n", + "South Gary\n", + "AR\n", + "14885\n", + "965.800.8174x1455929\n", + "Victoria\n", + "Rodriguez\n", + "F\n", + "2005-06-12\n", + "828 Lee Route\n", + "Lake Felicia\n", + "NC\n", + "44928\n", + "189.831.8711 \n", + " \n", + "

...

\n", + "

Total: 96

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex date_of_birth home_address home_city home_state home_zip home_phone \n", "+------------+ +------------+ +-----------+ +-----+ +------------+ +------------+ +------------+ +------------+ +----------+ +------------+\n", - "3 Derek Barrett M 2000-07-04 93045 Pamela P North Bradymou SD 33618 519-951-7205x5\n", - "6 Lucas Thomas M 2002-01-05 810 Williams D Port Hannahpor AK 66875 1407435812 \n", - "8 Deborah Vincent F 2001-01-10 237 Elizabeth North Jennifer UT 37335 +1-696-997-163\n", - "13 Kyle Neal M 2003-07-30 2079 Hayes Dri South Kimberly AZ 25811 294.223.3023 \n", - "15 Kyle Kirby M 2003-01-18 55693 Hudson U South Amytown VA 27199 366.457.5029x8\n", - "19 Gabrielle Carr F 2000-01-03 097 Gina Junct New Isaac CT 43134 204.887.5818x9\n", - "22 Dennis Shields M 2003-08-20 4385 Jonathan Benderview CO 53814 +1-650-949-328\n", - "27 Jason Cannon M 2001-03-12 575 Gross Cros Dominguezhaven IL 19583 0305674234 \n", - "29 Catherine Castro F 2000-05-08 506 Sue Flat Robinsonmouth WY 66233 +1-820-511-649\n", - "41 Brad Sanchez M 2002-04-04 15681 Smith Gr West Alexander NV 82139 030.223.4585x6\n", - "42 Debbie Rocha F 2001-01-14 9449 Johnson O Bryanttown HI 20252 (298)437-5761x\n", - "45 Andrew Rivera M 2003-12-21 21697 Steve Ha East Meredith CT 98221 257.005.7228 \n", + "0 Jillian Fischer F 2000-12-14 68627 Rodrigue East Anthony WY 64660 +1-837-213-818\n", + "1 Danielle Mccann F 2001-07-10 459 Watts Path Lake Charles PA 42226 2367757570 \n", + "2 Gabriel Austin M 2002-05-15 59647 Bruce Gr New Alexander OR 48511 +1-834-046-299\n", + "4 Aaron Dixon M 2001-06-18 57205 Clark La Millermouth AZ 90284 001-593-504-97\n", + "11 Kevin Walker M 2000-01-16 12139 Smith Hi Coleshire OK 82926 001-227-524-14\n", + "12 Bradley Johnson M 2002-10-27 44057 Amber Cl Martinborough WA 96529 1246630797 \n", + "17 Charles Burns M 2000-03-21 374 David Fork West Tylervill AR 66484 180-517-6772x0\n", + "18 Dawn Phillips F 2004-08-30 9205 Margaret East James CA 35646 +1-986-030-376\n", + "20 Mikayla Thomas F 2003-10-03 3104 Riggs Rad Mathewsview TX 41272 772.655.0583 \n", + "22 Kristen Wiley F 2003-06-21 743 Linda Stre Christopherhav WI 29738 873-334-4318x1\n", + "25 Dr. Ashley F 2005-03-16 1004 Fuller Ro South Gary AR 14885 965.800.8174x1\n", + "29 Victoria Rodriguez F 2005-06-12 828 Lee Route Lake Felicia NC 44928 189.831.8711 \n", " ...\n", - " (Total: 200)" + " (Total: 96)" ] }, - "execution_count": 28, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -1499,7 +1502,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -1508,231 +1511,230 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", - " \n", - " \n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " \n", - "\n", - "\n", + " /* Show the tooltip text when you mouse over the tooltip container */\n", + " .djtooltip:hover .djtooltiptext {\n", + " visibility: visible;\n", + " }\n", + " \n", + " \n", + " \n", + "
\n", + "
\n", - "

student_id

\n", - " university-wide ID number\n", - "
\n", - "

first_name

\n", - " \n", - "
\n", - "

last_name

\n", - " \n", - "
\n", - "

sex

\n", - " \n", - "
\n", - "

date_of_birth

\n", - " \n", - "
\n", - "

home_address

\n", - " mailing street address\n", - "
\n", - "

home_city

\n", - " mailing address\n", - "
\n", - "

home_state

\n", - " US state acronym: e.g. OH\n", - "
\n", - "

home_zip

\n", - " zipcode e.g. 93979-4979\n", - "
\n", - "

home_phone

\n", - " e.g. 414.657.6883x0881\n", - "
5ErikaPhillips
\n", + " \n", + " \n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
\n", + "

date_of_birth

\n", + " \n", + "
\n", + "

home_address

\n", + " mailing street address\n", + "
\n", + "

home_city

\n", + " mailing address\n", + "
\n", + "

home_state

\n", + " US state acronym: e.g. OH\n", + "
\n", + "

home_zip

\n", + " zipcode e.g. 93979-4979\n", + "
\n", + "

home_phone

\n", + " e.g. 414.657.6883x0881\n", + "
0JillianFischerF1988-03-31911 Tiffany Pike Apt. 570ChristophertownUT56135(889)801-9551x4395
7NancyFox2000-12-1468627 Rodriguez Center Suite 032East AnthonyWY64660+1-837-213-8181x775
1DanielleMccannF2001-07-10459 Watts Path Suite 309Lake CharlesPA422262367757570
5MackenzieBoyerF1984-05-1696581 Jackson PortsLake IanmouthLA320465707101635
8DeborahVincent1988-12-269458 Ashley Stravenue Apt. 044Port MelissalandOH54499669-684-3236
8JacquelineColonF2001-01-10237 Elizabeth Pass Suite 178North Jennifer1996-02-2464635 Duncan PlaceSolisburghUT37335+1-696-997-1635x317
9StephanieKoch76301(983)027-5735x055
9NicoleLongF1993-06-128303 Tiffany RestWilsonviewMA14163001-917-947-1447x650
11DonnaWilcox1986-10-24804 Sarah Rue Suite 661Port KristinamouthND07732568-928-6900x28524
13AnnaGoldenF1990-05-25540 Alexis GreenEast RachaelviewMO329759502795098
12DanielleRoth1999-03-09177 Robles PortJamesmouthPA57615862.977.2190
14JessicaRamosF1991-01-04697 Stacy WallSchmidtboroughME35610069.269.5700x454
18ChristineNewmanF1999-02-2800473 Daniel Freeway Apt. 706New EdwardNM45981287-445-7199x999
19GabrielleCarr1996-08-138318 Kenneth LakesNorth MeganNJ61279(736)120-0323x9695
16HeidiLewisF2000-01-03097 Gina Junction Apt. 926New IsaacCT43134204.887.5818x900
21MonicaWilson1992-03-07810 Wanda Pines Suite 244NicholechesterWA39909001-467-054-8928x041
18DawnPhillipsF1993-11-136255 William DivideWest KathyviewNC65452632.749.3286x370
23KatieBrown2004-08-309205 Margaret Common Apt. 133East JamesCA35646+1-986-030-3766x9704
19BethNielsenF1985-03-299844 Joshua GardenSouth ElizabethMN92773(058)445-6195x48931
26TiffanyJohnson1989-10-1452211 Joseph CoursePort AmandabergWY77459001-289-285-4689
20MikaylaThomasF1997-09-252752 Valerie Passage Apt. 583KennedyshireNC03101255.083.4385
29CatherineCastro2003-10-033104 Riggs Radial Apt. 751MathewsviewTX41272772.655.0583
22KristenWileyF2000-05-08506 Sue FlatRobinsonmouthWY66233+1-820-511-6491
\n", - "

...

\n", - "

Total: 465

\n", - " " + "2003-06-21\n", + "743 Linda Street Suite 948\n", + "Christopherhaven\n", + "WI\n", + "29738\n", + "873-334-4318x117 \n", + " \n", + "

...

\n", + "

Total: 152

\n", + " " ], "text/plain": [ "*student_id first_name last_name sex date_of_birth home_address home_city home_state home_zip home_phone \n", "+------------+ +------------+ +-----------+ +-----+ +------------+ +------------+ +------------+ +------------+ +----------+ +------------+\n", - "5 Erika Phillips F 1988-03-31 911 Tiffany Pi Christophertow UT 56135 (889)801-9551x\n", - "7 Nancy Fox F 1984-05-16 96581 Jackson Lake Ianmouth LA 32046 5707101635 \n", - "8 Deborah Vincent F 2001-01-10 237 Elizabeth North Jennifer UT 37335 +1-696-997-163\n", - "9 Stephanie Koch F 1993-06-12 8303 Tiffany R Wilsonview MA 14163 001-917-947-14\n", - "11 Donna Wilcox F 1990-05-25 540 Alexis Gre East Rachaelvi MO 32975 9502795098 \n", - "12 Danielle Roth F 1991-01-04 697 Stacy Wall Schmidtborough ME 35610 069.269.5700x4\n", - "18 Christine Newman F 1999-02-28 00473 Daniel F New Edward NM 45981 287-445-7199x9\n", - "19 Gabrielle Carr F 2000-01-03 097 Gina Junct New Isaac CT 43134 204.887.5818x9\n", - "21 Monica Wilson F 1993-11-13 6255 William D West Kathyview NC 65452 632.749.3286x3\n", - "23 Katie Brown F 1985-03-29 9844 Joshua Ga South Elizabet MN 92773 (058)445-6195x\n", - "26 Tiffany Johnson F 1997-09-25 2752 Valerie P Kennedyshire NC 03101 255.083.4385 \n", - "29 Catherine Castro F 2000-05-08 506 Sue Flat Robinsonmouth WY 66233 +1-820-511-649\n", + "0 Jillian Fischer F 2000-12-14 68627 Rodrigue East Anthony WY 64660 +1-837-213-818\n", + "1 Danielle Mccann F 2001-07-10 459 Watts Path Lake Charles PA 42226 2367757570 \n", + "5 Mackenzie Boyer F 1988-12-26 9458 Ashley St Port Melissala OH 54499 669-684-3236 \n", + "8 Jacqueline Colon F 1996-02-24 64635 Duncan P Solisburgh UT 76301 (983)027-5735x\n", + "9 Nicole Long F 1986-10-24 804 Sarah Rue Port Kristinam ND 07732 568-928-6900x2\n", + "13 Anna Golden F 1999-03-09 177 Robles Por Jamesmouth PA 57615 862.977.2190 \n", + "14 Jessica Ramos F 1996-08-13 8318 Kenneth L North Megan NJ 61279 (736)120-0323x\n", + "16 Heidi Lewis F 1992-03-07 810 Wanda Pine Nicholechester WA 39909 001-467-054-89\n", + "18 Dawn Phillips F 2004-08-30 9205 Margaret East James CA 35646 +1-986-030-376\n", + "19 Beth Nielsen F 1989-10-14 52211 Joseph C Port Amandaber WY 77459 001-289-285-46\n", + "20 Mikayla Thomas F 2003-10-03 3104 Riggs Rad Mathewsview TX 41272 772.655.0583 \n", + "22 Kristen Wiley F 2003-06-21 743 Linda Stre Christopherhav WI 29738 873-334-4318x1\n", " ...\n", - " (Total: 465)" + " (Total: 152)" ] }, - "execution_count": 35, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -1750,43 +1752,1980 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array([( 0, 'Jillian', 'Fischer', 'F', datetime.date(2000, 12, 14), '68627 Rodriguez Center Suite 032', 'East Anthony', 'WY', '64660', '+1-837-213-8181x775'),\n", + " ( 1, 'Danielle', 'Mccann', 'F', datetime.date(2001, 7, 10), '459 Watts Path Suite 309', 'Lake Charles', 'PA', '42226', '2367757570'),\n", + " ( 5, 'Mackenzie', 'Boyer', 'F', datetime.date(1988, 12, 26), '9458 Ashley Stravenue Apt. 044', 'Port Melissaland', 'OH', '54499', '669-684-3236'),\n", + " ( 8, 'Jacqueline', 'Colon', 'F', datetime.date(1996, 2, 24), '64635 Duncan Place', 'Solisburgh', 'UT', '76301', '(983)027-5735x055'),\n", + " ( 9, 'Nicole', 'Long', 'F', datetime.date(1986, 10, 24), '804 Sarah Rue Suite 661', 'Port Kristinamouth', 'ND', '07732', '568-928-6900x28524'),\n", + " ( 13, 'Anna', 'Golden', 'F', datetime.date(1999, 3, 9), '177 Robles Port', 'Jamesmouth', 'PA', '57615', '862.977.2190'),\n", + " ( 14, 'Jessica', 'Ramos', 'F', datetime.date(1996, 8, 13), '8318 Kenneth Lakes', 'North Megan', 'NJ', '61279', '(736)120-0323x9695'),\n", + " ( 16, 'Heidi', 'Lewis', 'F', datetime.date(1992, 3, 7), '810 Wanda Pines Suite 244', 'Nicholechester', 'WA', '39909', '001-467-054-8928x041'),\n", + " ( 18, 'Dawn', 'Phillips', 'F', datetime.date(2004, 8, 30), '9205 Margaret Common Apt. 133', 'East James', 'CA', '35646', '+1-986-030-3766x9704'),\n", + " ( 19, 'Beth', 'Nielsen', 'F', datetime.date(1989, 10, 14), '52211 Joseph Course', 'Port Amandaberg', 'WY', '77459', '001-289-285-4689'),\n", + " ( 20, 'Mikayla', 'Thomas', 'F', datetime.date(2003, 10, 3), '3104 Riggs Radial Apt. 751', 'Mathewsview', 'TX', '41272', '772.655.0583'),\n", + " ( 22, 'Kristen', 'Wiley', 'F', datetime.date(2003, 6, 21), '743 Linda Street Suite 948', 'Christopherhaven', 'WI', '29738', '873-334-4318x117'),\n", + " ( 24, 'Karen', 'Hall', 'F', datetime.date(1991, 1, 1), '802 Oconnor Shoal', 'Courtneyside', 'VA', '76699', '001-450-895-2937x557'),\n", + " ( 25, 'Dr.', 'Ashley', 'F', datetime.date(2005, 3, 16), '1004 Fuller Route Suite 401', 'South Gary', 'AR', '14885', '965.800.8174x14559'),\n", + " ( 27, 'Tara', 'Moore', 'F', datetime.date(1996, 9, 25), '09753 Timothy Plains Suite 918', 'South Brandichester', 'WV', '20935', '098-675-6040'),\n", + " ( 29, 'Victoria', 'Rodriguez', 'F', datetime.date(2005, 6, 12), '828 Lee Route', 'Lake Felicia', 'NC', '44928', '189.831.8711'),\n", + " ( 30, 'Debbie', 'Patterson', 'F', datetime.date(1994, 8, 29), '5977 Donald Hills Suite 426', 'North Jillian', 'VA', '86148', '573-589-7894'),\n", + " ( 31, 'Karen', 'Lee', 'F', datetime.date(2001, 5, 28), '92397 Smith Court Suite 681', 'New Robin', 'OR', '03775', '001-504-939-0893x736'),\n", + " ( 33, 'Kimberly', 'Carey', 'F', datetime.date(1998, 9, 7), '92403 Nancy Mills Apt. 662', 'Port Laurenside', 'NY', '99368', '(097)580-1867x2670'),\n", + " ( 34, 'Robin', 'Jones', 'F', datetime.date(1991, 4, 4), '872 Jackson Pines Suite 396', 'Youngborough', 'MA', '74118', '+1-092-142-9264x4959'),\n", + " ( 37, 'Heather', 'Humphrey', 'F', datetime.date(2000, 3, 12), '728 Amy Groves Apt. 457', 'South Alvin', 'IN', '27823', '4145328004'),\n", + " ( 38, 'Jasmine', 'Hicks', 'F', datetime.date(1986, 6, 22), '92100 Nunez Mountain Suite 341', 'New Rachaelside', 'DC', '53689', '5590657043'),\n", + " ( 39, 'Amanda', 'Wang', 'F', datetime.date(2002, 7, 9), '028 James Avenue', 'Donnaburgh', 'NV', '37215', '251-324-2667'),\n", + " ( 40, 'Amanda', 'Rosario', 'F', datetime.date(1999, 4, 10), '9563 Michael Pine Suite 931', 'Michaelshire', 'WV', '21208', '001-576-734-7225x242'),\n", + " ( 43, 'Amanda', 'Arroyo', 'F', datetime.date(1992, 4, 30), '49408 Williams Brook', 'Jennifermouth', 'NE', '68506', '126-624-6833'),\n", + " ( 45, 'Kelly', 'Wheeler', 'F', datetime.date(1999, 8, 28), '5199 Grace Stream', 'North Regina', 'ID', '42797', '(852)471-1509x6905'),\n", + " ( 48, 'Kimberly', 'Raymond', 'F', datetime.date(2004, 1, 28), '69277 Ray Key', 'South Danielletown', 'ID', '64803', '022.172.5672x603'),\n", + " ( 51, 'Deanna', 'Valdez', 'F', datetime.date(2001, 10, 20), '98307 Jennifer Track', 'South Johnmouth', 'FL', '54437', '788.587.3743'),\n", + " ( 53, 'Kristen', 'Jenkins', 'F', datetime.date(1989, 12, 6), '7196 Brian Center', 'Barbaraview', 'NE', '95825', '+1-816-931-7241x906'),\n", + " ( 54, 'Jessica', 'Bennett', 'F', datetime.date(2003, 8, 26), '615 Sharon Gateway', 'Port Sean', 'SC', '03709', '867.612.4267x9135'),\n", + " ( 55, 'Elizabeth', 'Howell', 'F', datetime.date(2002, 9, 4), '2352 Benjamin Gateway Suite 996', 'Josephburgh', 'IL', '50989', '001-719-428-3855'),\n", + " ( 56, 'Dr.', 'Bethany', 'F', datetime.date(2003, 9, 14), '074 Justin Spurs Apt. 653', 'West Davidview', 'WA', '58491', '839-843-6610'),\n", + " ( 59, 'Kristina', 'Kirby', 'F', datetime.date(1988, 5, 22), '89489 Young Way', 'Benjaminstad', 'ID', '20962', '+1-494-205-1237x9988'),\n", + " ( 61, 'Carolyn', 'Miller', 'F', datetime.date(2002, 9, 18), '955 Brandon Mill Suite 104', 'Tuckerton', 'IN', '83326', '308.665.7407'),\n", + " ( 64, 'Ashley', 'Young', 'F', datetime.date(2000, 2, 22), '36721 Simpson Lights Suite 035', 'Smithberg', 'OK', '84539', '733.287.7040'),\n", + " ( 66, 'Kristin', 'Mason', 'F', datetime.date(1987, 4, 14), '31397 Stone Parkway Suite 353', 'Lake Amanda', 'DC', '09007', '696.480.4255x92770'),\n", + " ( 67, 'Megan', 'Martinez', 'F', datetime.date(1994, 12, 22), '5276 Alexander Avenue Suite 928', 'North Rodney', 'KY', '62441', '(432)914-1079'),\n", + " ( 68, 'Janet', 'Anderson', 'F', datetime.date(2002, 6, 28), '206 Smith Viaduct Suite 699', 'Heiditon', 'SD', '81142', '529.788.9930'),\n", + " ( 69, 'Vanessa', 'Copeland', 'F', datetime.date(1995, 10, 28), '9695 Samuel Drive Suite 092', 'Christopherburgh', 'WI', '51730', '915-931-4672x9407'),\n", + " ( 70, 'Kathleen', 'Reed', 'F', datetime.date(1999, 8, 11), '41882 Allen Walk Apt. 899', 'Sandrabury', 'LA', '56451', '+1-106-887-8907x7524'),\n", + " ( 71, 'Katherine', 'Jenkins', 'F', datetime.date(1998, 12, 2), '51656 Joseph Rapid Apt. 522', 'New Richardville', 'KY', '63822', '+1-522-727-7641x7839'),\n", + " ( 74, 'Katherine', 'Potter', 'F', datetime.date(2005, 3, 17), '477 Carrillo Street', 'West Emily', 'RI', '62414', '164.047.7857'),\n", + " ( 75, 'Teresa', 'Carter', 'F', datetime.date(1996, 2, 26), '597 Aimee Locks', 'Johnfurt', 'NE', '45270', '408-191-1318x661'),\n", + " ( 77, 'Rachel', 'Bowen', 'F', datetime.date(2002, 5, 25), '547 Taylor Crest', 'Kellytown', 'ME', '61328', '707-544-3298x4719'),\n", + " ( 78, 'Emily', 'Jones', 'F', datetime.date(2001, 10, 18), '502 Cameron Estate', 'South Thomas', 'OK', '51464', '001-280-466-4043x825'),\n", + " ( 79, 'Jennifer', 'Nunez', 'F', datetime.date(1989, 3, 1), '158 James Green Apt. 156', 'West Jerry', 'CA', '77440', '(571)077-8320'),\n", + " ( 80, 'Jennifer', 'Nguyen', 'F', datetime.date(1993, 11, 10), '6937 Jennifer Lock Apt. 321', 'Deanstad', 'NY', '48675', '001-267-589-2918x447'),\n", + " ( 81, 'Jessica', 'Clay', 'F', datetime.date(1997, 5, 22), '536 Hernandez Walks Apt. 972', 'South Alanmouth', 'SD', '96555', '6697468738'),\n", + " ( 83, 'Kristin', 'Jones', 'F', datetime.date(1990, 4, 17), '10480 Walker Trail Apt. 498', 'New Robertland', 'RI', '01171', '+1-421-682-5503x016'),\n", + " ( 86, 'Andrea', 'Moreno', 'F', datetime.date(1990, 11, 24), '5411 Smith Ways', 'Sanchezberg', 'LA', '26114', '001-988-175-2362'),\n", + " ( 91, 'Sara', 'Huff', 'F', datetime.date(2005, 2, 20), '017 Rich Hills Suite 633', 'Brownchester', 'CT', '67581', '(933)377-7739x6876'),\n", + " ( 96, 'Kimberly', 'Butler', 'F', datetime.date(1994, 10, 13), '48400 Rodriguez Street', 'Lake Robertstad', 'KS', '77376', '6395340351'),\n", + " ( 97, 'Tracy', 'Baker', 'F', datetime.date(2001, 2, 1), '79211 Nathaniel Drive Suite 386', 'South Deannashire', 'IL', '28281', '+1-005-844-5959'),\n", + " (101, 'Andrea', 'Franklin', 'F', datetime.date(1996, 6, 9), '4446 Taylor Plaza', 'Port Davidside', 'AR', '93278', '493-991-1706x07012'),\n", + " (102, 'Alyssa', 'Brown', 'F', datetime.date(2004, 6, 9), '20243 Daniel Manor Apt. 402', 'Cynthiaberg', 'MN', '22079', '001-925-888-7154x436'),\n", + " (107, 'Brenda', 'Sanders', 'F', datetime.date(1990, 4, 25), '189 Stephen Knolls', 'Lake Amyborough', 'AR', '93809', '453.136.2198'),\n", + " (109, 'Deanna', 'Cox', 'F', datetime.date(2003, 9, 24), '164 Chapman Drive Apt. 274', 'South Robert', 'NC', '28885', '(235)873-8575'),\n", + " (111, 'Heather', 'Alvarado', 'F', datetime.date(2003, 2, 8), '042 Rebecca Mission', 'North Donna', 'MD', '87937', '803.854.9834'),\n", + " (116, 'Amber', 'Blankenship', 'F', datetime.date(1993, 12, 12), '41843 Jones Heights', 'Port Kara', 'CT', '78824', '+1-632-246-1077x531'),\n", + " (117, 'Kathryn', 'Davis', 'F', datetime.date(1994, 6, 26), '71512 Nicholas Rapids', 'Port Traciberg', 'MA', '84122', '001-011-104-2980x973'),\n", + " (118, 'Kristina', 'Norman', 'F', datetime.date(2005, 3, 4), '5665 Dennis Mill', 'Perkinschester', 'PA', '38683', '816-936-8115x18690'),\n", + " (119, 'Alicia', 'Sweeney', 'F', datetime.date(1996, 2, 6), '111 Mackenzie Junctions', 'West Linda', 'IN', '93938', '894-678-6968x11463'),\n", + " (122, 'Rebecca', 'Copeland', 'F', datetime.date(1994, 12, 13), '89462 Lewis Expressway Apt. 713', 'Haleymouth', 'NY', '78212', '+1-614-640-8342x007'),\n", + " (123, 'Anna', 'Cunningham', 'F', datetime.date(2000, 1, 23), '293 Cox Pine', 'Kruegerborough', 'TN', '94115', '095.131.3694'),\n", + " (125, 'Kylie', 'Diaz', 'F', datetime.date(2003, 8, 17), '4603 Douglas Fort Apt. 494', 'Colemanview', 'WI', '03325', '052.106.6014x95876'),\n", + " (126, 'Kristin', 'Yates', 'F', datetime.date(1989, 9, 26), '7297 Danielle Wells Apt. 787', 'Bruceview', 'AK', '01608', '471-379-8060'),\n", + " (127, 'Kayla', 'Sawyer', 'F', datetime.date(1987, 4, 1), '147 Peter Crest', 'Medinamouth', 'SC', '36063', '155.903.2519x32943'),\n", + " (128, 'Megan', 'Rodriguez', 'F', datetime.date(1990, 10, 23), '9126 Brown Plaza', 'New David', 'MD', '28416', '924-150-2547'),\n", + " (132, 'Deborah', 'Callahan', 'F', datetime.date(1992, 9, 21), '8147 Madison Wells', 'Moyerbury', 'MN', '55249', '815.014.3670'),\n", + " (133, 'Natalie', 'Thomas', 'F', datetime.date(2000, 4, 29), '18291 Marcus Lock Apt. 641', 'Carlosmouth', 'LA', '41866', '007.913.3881x94110'),\n", + " (137, 'Melanie', 'Miller', 'F', datetime.date(1994, 1, 4), '1921 Michael Courts', 'Thomasberg', 'TN', '95425', '+1-392-739-5934x213'),\n", + " (138, 'Amber', 'Peters', 'F', datetime.date(1995, 9, 4), '501 Burnett Inlet', 'West Brittany', 'VT', '08798', '853-889-0428x9721'),\n", + " (139, 'Kristen', 'Thomas', 'F', datetime.date(1993, 5, 31), '10941 Virginia Island', 'Penningtonhaven', 'IN', '79891', '(192)078-6665'),\n", + " (144, 'Samantha', 'Clark', 'F', datetime.date(1996, 6, 1), '9094 Owens Causeway Suite 106', 'Martinezland', 'WY', '49371', '975.309.8113x664'),\n", + " (148, 'Felicia', 'Vaughn', 'F', datetime.date(2001, 8, 5), '90380 Joshua Landing', 'New Steven', 'SD', '37352', '+1-918-046-4526x727'),\n", + " (149, 'Debra', 'West', 'F', datetime.date(2003, 11, 9), '49508 Kelly Springs', 'Hallland', 'MD', '01505', '(428)591-2046x3225'),\n", + " (151, 'Melissa', 'Thomas', 'F', datetime.date(2002, 6, 5), '454 Mike Walk Suite 188', 'Sarashire', 'IN', '93084', '(707)472-4151x17712'),\n", + " (154, 'Tanya', 'Williams', 'F', datetime.date(1985, 11, 19), '427 Ann Isle Apt. 757', 'West Kristinaville', 'CO', '45548', '001-440-604-4666x725'),\n", + " (155, 'Emily', 'Byrd', 'F', datetime.date(2004, 4, 3), '650 Roberts Road', 'West Zacharyfort', 'WY', '79775', '(443)399-6944'),\n", + " (157, 'Monica', 'Klein', 'F', datetime.date(1998, 12, 9), '53050 Garcia Street Apt. 359', 'Butlerstad', 'DE', '87791', '+1-510-661-1680'),\n", + " (158, 'Crystal', 'Leach', 'F', datetime.date(1991, 12, 17), '88760 Elizabeth Station', 'East Scott', 'IN', '76311', '717.446.6353x0889'),\n", + " (160, 'Maureen', 'Simon', 'F', datetime.date(1996, 10, 5), '9799 Julie Plaza Suite 583', 'Barryport', 'IN', '87386', '+1-365-486-0536x712'),\n", + " (161, 'Wendy', 'Mcclure', 'F', datetime.date(2005, 5, 13), '93627 Hansen Drives', 'New Lisa', 'KS', '01367', '968.733.9273x1230'),\n", + " (162, 'Veronica', 'Jackson', 'F', datetime.date(1987, 9, 10), '55017 Anna Viaduct', 'Michaelbury', 'MN', '76244', '(354)996-9659x86033'),\n", + " (164, 'Amy', 'Williams', 'F', datetime.date(1998, 7, 29), '334 Weeks Club Suite 643', 'Larsonborough', 'ME', '18462', '409-286-7863'),\n", + " (168, 'Alyssa', 'Guerra', 'F', datetime.date(1989, 12, 10), '5551 John Stream', 'West Erikafort', 'TX', '39968', '+1-384-619-7074'),\n", + " (169, 'Deborah', 'Cline', 'F', datetime.date(1996, 3, 3), '91196 Anthony Wells', 'Brownhaven', 'MT', '23238', '(671)274-4744x719'),\n", + " (171, 'Diana', 'Wagner', 'F', datetime.date(2005, 10, 21), '957 Wong Lights', 'East Matthew', 'MA', '01000', '(282)563-2014x87937'),\n", + " (172, 'Tracy', 'Patton', 'F', datetime.date(2005, 4, 6), '82521 Brooks Tunnel Apt. 807', 'West Richardhaven', 'NH', '27416', '856.087.2857'),\n", + " (173, 'Taylor', 'Fleming', 'F', datetime.date(1992, 12, 8), '96752 Villa Stream Apt. 607', 'North Sarahchester', 'LA', '55882', '642-759-4869x1650'),\n", + " (175, 'Melissa', 'Keller', 'F', datetime.date(1994, 8, 23), '2874 Saunders Glen Suite 317', 'Denisebury', 'TN', '65422', '(484)124-9158x3337'),\n", + " (176, 'Crystal', 'Short', 'F', datetime.date(1996, 10, 11), '14918 Brown Walk', 'West Jeff', 'IN', '19394', '001-611-275-1179x645'),\n", + " (182, 'Katie', 'Palmer', 'F', datetime.date(1989, 8, 24), '439 Wright Prairie Suite 796', 'Fullerborough', 'ME', '03583', '+1-438-161-7483x788'),\n", + " (184, 'Jordan', 'Jones', 'F', datetime.date(1993, 8, 29), '227 Christy Causeway Suite 269', 'Port Brandonchester', 'CT', '34678', '(152)951-9193x444'),\n", + " (187, 'Kimberly', 'Anthony', 'F', datetime.date(1996, 1, 15), '71203 Ray Spur', 'Torrestown', 'KY', '09573', '(786)320-7649x2637'),\n", + " (188, 'Ashley', 'Guzman', 'F', datetime.date(2001, 11, 14), '011 Fowler Drive Apt. 620', 'Garciamouth', 'MI', '94068', '001-809-948-0078x762'),\n", + " (189, 'Kelly', 'Thompson', 'F', datetime.date(2004, 4, 26), '33144 Jeffery Courts Suite 171', 'North Isaiah', 'OR', '50923', '001-437-662-7268x603'),\n", + " (192, 'Margaret', 'Hughes', 'F', datetime.date(1986, 11, 17), '4879 Michelle Land Suite 673', 'Jenniferstad', 'PA', '27286', '001-390-553-2632'),\n", + " (193, 'Lisa', 'Escobar', 'F', datetime.date(1998, 3, 13), '926 Stark Crossing', 'South Bryan', 'MS', '86227', '(331)589-7870x58178'),\n", + " (198, 'Sarah', 'Odonnell', 'F', datetime.date(1989, 9, 13), '18158 Ellison Hills Apt. 244', 'Travisfurt', 'AL', '04641', '(792)274-1066x26038'),\n", + " (199, 'Stephanie', 'Curtis', 'F', datetime.date(1995, 11, 14), '133 Christopher Junction Apt. 134', 'South Jennifer', 'CA', '62643', '614-287-6200x23188'),\n", + " (200, 'Kimberly', 'Taylor', 'F', datetime.date(1987, 8, 14), '42166 Flores Island', 'Roberthaven', 'MT', '17048', '+1-689-653-0999'),\n", + " (201, 'Lacey', 'Taylor', 'F', datetime.date(1988, 4, 26), '97005 Lisa Mill Suite 678', 'Newtonshire', 'TN', '69198', '+1-357-502-7339x1514'),\n", + " (202, 'Melissa', 'Little', 'F', datetime.date(1999, 7, 13), '383 Haynes Court', 'North Lindsey', 'NY', '29588', '024.540.9045'),\n", + " (206, 'Karen', 'Bryan', 'F', datetime.date(1999, 6, 13), '3670 Carol Village Suite 907', 'South Christinaville', 'GA', '37283', '001-359-306-4754x614'),\n", + " (207, 'Anita', 'Harmon', 'F', datetime.date(1995, 6, 27), '9485 Werner Underpass', 'Jeffreyview', 'WV', '39997', '064.111.8438'),\n", + " (208, 'Beth', 'Smith', 'F', datetime.date(2004, 9, 30), '958 Kimberly Forges', 'Newmanland', 'NE', '78284', '492.071.6510'),\n", + " (209, 'Carrie', 'Dennis', 'F', datetime.date(1993, 11, 12), '3666 Adams Vista', 'North Jenniferland', 'SD', '02830', '+1-395-365-9523x6997'),\n", + " (210, 'Paula', 'Perez', 'F', datetime.date(2000, 8, 15), '17911 Frazier Roads', 'Port Tasha', 'UT', '21725', '405.906.1669'),\n", + " (213, 'Brianna', 'Rose', 'F', datetime.date(1998, 3, 31), '0428 Gomez Trail Apt. 639', 'North Donna', 'WA', '26718', '001-823-285-7191x368'),\n", + " (220, 'Kathryn', 'Lopez', 'F', datetime.date(1988, 3, 25), '861 Tanya Knolls', 'Payneside', 'NJ', '90616', '(074)095-3943x06918'),\n", + " (221, 'Sarah', 'Myers', 'F', datetime.date(1993, 1, 26), '34262 Christopher Street', 'Cabrerabury', 'HI', '26895', '915.044.0595'),\n", + " (224, 'Donna', 'Smith', 'F', datetime.date(2004, 12, 19), '804 Mccoy Turnpike Suite 847', 'Bautistafurt', 'WI', '29114', '(046)527-9112x706'),\n", + " (226, 'Shelley', 'Brooks', 'F', datetime.date(2005, 9, 27), '31828 Taylor Glen Suite 101', 'New Jenniferhaven', 'NJ', '44670', '+1-491-708-0414x864'),\n", + " (228, 'Andrea', 'Barrett', 'F', datetime.date(1993, 8, 11), '7100 Scott Lake', 'Kristenstad', 'OK', '09274', '001-500-223-8945x457'),\n", + " (234, 'Katelyn', 'Hoover', 'F', datetime.date(1997, 12, 24), '9315 Christopher Road', 'Loriburgh', 'CA', '75454', '275.704.7134x661'),\n", + " (235, 'Shannon', 'Williams', 'F', datetime.date(2002, 7, 8), '08663 Kimberly Expressway Apt. 575', 'South Wyatt', 'AL', '80993', '314-058-0010'),\n", + " (239, 'Yvette', 'Galloway', 'F', datetime.date(2002, 7, 24), '12076 Anthony Square', 'Samueltown', 'NY', '34260', '(878)866-9801x91611'),\n", + " (241, 'Sandra', 'Winters', 'F', datetime.date(2005, 7, 31), '907 Mario Lodge Apt. 942', 'Shermanville', 'ND', '45545', '+1-753-365-4045'),\n", + " (248, 'Richard', 'Noble', 'M', datetime.date(2003, 2, 5), '7977 Adams Crossroad Suite 214', 'Port Catherineland', 'UT', '34911', '458.117.5719'),\n", + " (249, 'Ashley', 'Thomas', 'F', datetime.date(1996, 8, 29), '241 Katie Fort Apt. 087', 'New Ebony', 'ME', '26233', '135-652-0859x3049'),\n", + " (251, 'Ashley', 'Miller', 'F', datetime.date(1988, 6, 13), '1805 Alexis Villages', 'Morrisonton', 'MD', '93116', '(263)336-5912'),\n", + " (254, 'Deanna', 'Price', 'F', datetime.date(1994, 11, 4), '120 Edwards Expressway Suite 511', 'Kathleenberg', 'CA', '19876', '001-940-447-1052x158'),\n", + " (258, 'Julie', 'Jones', 'F', datetime.date(2005, 8, 2), '35304 Rachel Meadows Suite 288', 'North Jeffreyberg', 'AZ', '48886', '141-934-7302x6340'),\n", + " (259, 'Monica', 'Hill', 'F', datetime.date(1992, 10, 18), '945 Angela Key', 'Johnchester', 'GA', '23266', '0750320331'),\n", + " (260, 'Joanne', 'Williams', 'F', datetime.date(2001, 2, 7), '85254 Janet Pines', 'Lake Daniel', 'AZ', '34031', '623.410.2275'),\n", + " (262, 'Debra', 'Riggs', 'F', datetime.date(2002, 5, 3), '090 Andrew Mountains Apt. 054', 'New Amandachester', 'WA', '61679', '001-635-536-1950x612'),\n", + " (264, 'Heidi', 'Charles', 'F', datetime.date(1990, 3, 15), '927 Chandler Groves Suite 929', 'Leeville', 'MA', '27167', '(160)618-6264x340'),\n", + " (266, 'Valerie', 'Smith', 'F', datetime.date(1989, 1, 22), '4709 Patrick Wall', 'West Ericview', 'AL', '73935', '(783)138-7164'),\n", + " (268, 'Debra', 'Schmitt', 'F', datetime.date(1992, 12, 22), '74229 James Hills Apt. 780', 'East Kristina', 'IN', '43119', '516.311.9867'),\n", + " (269, 'Veronica', 'Anderson', 'F', datetime.date(1997, 5, 19), '0043 Baker Springs', 'Kristinaton', 'UT', '04908', '(811)585-2197x666'),\n", + " (271, 'Elizabeth', 'Brock', 'F', datetime.date(1987, 3, 6), '8230 Mitchell Extension Apt. 275', 'Port Anthony', 'CA', '31032', '190-577-0466x2936'),\n", + " (273, 'Brenda', 'Lynch', 'F', datetime.date(2002, 9, 10), '11630 Jeremy Mountains', 'Austinchester', 'SC', '45091', '(460)652-5911x142'),\n", + " (275, 'Diane', 'Walker', 'F', datetime.date(2002, 6, 22), '929 Olivia Turnpike', 'Lake Keithport', 'DE', '11107', '1672377368'),\n", + " (276, 'Sara', 'Murphy', 'F', datetime.date(1987, 7, 5), '178 Smith Prairie', 'West Allison', 'ND', '93840', '610.384.6473x01662'),\n", + " (278, 'Shannon', 'Mayer', 'F', datetime.date(1997, 4, 10), '8730 Derrick Mews Suite 666', 'Craneborough', 'NV', '24146', '001-006-189-0389x612'),\n", + " (279, 'Crystal', 'Parker', 'F', datetime.date(2001, 11, 28), '1314 Jessica Causeway', 'Port Stephen', 'GA', '98006', '(321)139-5367'),\n", + " (280, 'Tamara', 'Walter', 'F', datetime.date(2001, 8, 18), '136 Garrison Prairie Apt. 775', 'South Sara', 'IN', '72450', '+1-823-985-9579x9827'),\n", + " (281, 'Amber', 'Benson', 'F', datetime.date(1988, 3, 21), '90660 Hamilton Orchard Apt. 932', 'Matthewstown', 'OK', '20573', '001-513-126-8556x683'),\n", + " (282, 'Colleen', 'Barnes', 'F', datetime.date(1992, 1, 19), '959 Lin Common Apt. 811', 'Port Phillip', 'MO', '72239', '341.284.4253x580'),\n", + " (283, 'Paula', 'Clark', 'F', datetime.date(2005, 9, 30), '49434 Robert Shore', 'Ortizport', 'MI', '20527', '664-842-9310'),\n", + " (284, 'Jennifer', 'Cole', 'F', datetime.date(1986, 11, 18), '821 Kline Valleys Apt. 697', 'South Jamesfort', 'WI', '57201', '8222564998'),\n", + " (286, 'Angela', 'Hill', 'F', datetime.date(2000, 7, 2), '126 Collins Neck', 'Seanfurt', 'CT', '98022', '213-109-1553x39625'),\n", + " (287, 'Mrs.', 'Lisa', 'F', datetime.date(1994, 10, 16), '2117 Walls Harbor Suite 967', 'Lake Anthony', 'WI', '41121', '+1-886-620-3505'),\n", + " (288, 'Olivia', 'Martinez', 'F', datetime.date(2001, 6, 25), '0897 Brian Union', 'Fosterfurt', 'ND', '42558', '8320317842'),\n", + " (289, 'Alyssa', 'Oliver', 'F', datetime.date(1999, 7, 30), '979 Daisy Cliffs', 'Maureenside', 'NY', '41650', '(927)504-5856'),\n", + " (290, 'Barbara', 'Hicks', 'F', datetime.date(2003, 2, 14), '06525 Coleman Via', 'Port Vanessatown', 'DC', '80068', '(403)892-5401x1797'),\n", + " (291, 'Shari', 'Rodriguez', 'F', datetime.date(2002, 4, 7), '14993 Reeves Cove', 'East Frederick', 'MN', '14832', '436.215.4569x041'),\n", + " (292, 'Wendy', 'Mathews', 'F', datetime.date(2003, 12, 13), '8728 Jamie Courts', 'New Leefort', 'AL', '66380', '+1-716-103-4197x654'),\n", + " (296, 'Michelle', 'George', 'F', datetime.date(1994, 1, 2), '56285 Stephanie Wall Suite 800', 'Vazquezside', 'AR', '02142', '(683)009-1622x26181'),\n", + " (298, 'Christine', 'Johnson', 'F', datetime.date(2003, 2, 14), '4725 Petersen Via', 'Clarkburgh', 'NC', '75437', '+1-281-129-5589x225'),\n", + " (299, 'Lisa', 'Sheppard', 'F', datetime.date(2004, 4, 2), '95923 Reynolds Fork Suite 719', 'West Laura', 'LA', '23546', '001-842-369-3244x325')],\n", + " dtype=[('student_id', '\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
first_namelast_namesexdate_of_birthhome_addresshome_cityhome_statehome_ziphome_phone
student_id
0JillianFischerF2000-12-1468627 Rodriguez Center Suite 032East AnthonyWY64660+1-837-213-8181x775
1DanielleMccannF2001-07-10459 Watts Path Suite 309Lake CharlesPA422262367757570
5MackenzieBoyerF1988-12-269458 Ashley Stravenue Apt. 044Port MelissalandOH54499669-684-3236
8JacquelineColonF1996-02-2464635 Duncan PlaceSolisburghUT76301(983)027-5735x055
9NicoleLongF1986-10-24804 Sarah Rue Suite 661Port KristinamouthND07732568-928-6900x28524
..............................
291ShariRodriguezF2002-04-0714993 Reeves CoveEast FrederickMN14832436.215.4569x041
292WendyMathewsF2003-12-138728 Jamie CourtsNew LeefortAL66380+1-716-103-4197x654
296MichelleGeorgeF1994-01-0256285 Stephanie Wall Suite 800VazquezsideAR02142(683)009-1622x26181
298ChristineJohnsonF2003-02-144725 Petersen ViaClarkburghNC75437+1-281-129-5589x225
299LisaSheppardF2004-04-0295923 Reynolds Fork Suite 719West LauraLA23546001-842-369-3244x325
\n", + "

152 rows × 9 columns

\n", + "" + ], + "text/plain": [ + " first_name last_name sex date_of_birth \\\n", + "student_id \n", + "0 Jillian Fischer F 2000-12-14 \n", + "1 Danielle Mccann F 2001-07-10 \n", + "5 Mackenzie Boyer F 1988-12-26 \n", + "8 Jacqueline Colon F 1996-02-24 \n", + "9 Nicole Long F 1986-10-24 \n", + "... ... ... .. ... \n", + "291 Shari Rodriguez F 2002-04-07 \n", + "292 Wendy Mathews F 2003-12-13 \n", + "296 Michelle George F 1994-01-02 \n", + "298 Christine Johnson F 2003-02-14 \n", + "299 Lisa Sheppard F 2004-04-02 \n", + "\n", + " home_address home_city home_state \\\n", + "student_id \n", + "0 68627 Rodriguez Center Suite 032 East Anthony WY \n", + "1 459 Watts Path Suite 309 Lake Charles PA \n", + "5 9458 Ashley Stravenue Apt. 044 Port Melissaland OH \n", + "8 64635 Duncan Place Solisburgh UT \n", + "9 804 Sarah Rue Suite 661 Port Kristinamouth ND \n", + "... ... ... ... \n", + "291 14993 Reeves Cove East Frederick MN \n", + "292 8728 Jamie Courts New Leefort AL \n", + "296 56285 Stephanie Wall Suite 800 Vazquezside AR \n", + "298 4725 Petersen Via Clarkburgh NC \n", + "299 95923 Reynolds Fork Suite 719 West Laura LA \n", + "\n", + " home_zip home_phone \n", + "student_id \n", + "0 64660 +1-837-213-8181x775 \n", + "1 42226 2367757570 \n", + "5 54499 669-684-3236 \n", + "8 76301 (983)027-5735x055 \n", + "9 07732 568-928-6900x28524 \n", + "... ... ... \n", + "291 14832 436.215.4569x041 \n", + "292 66380 +1-716-103-4197x654 \n", + "296 02142 (683)009-1622x26181 \n", + "298 75437 +1-281-129-5589x225 \n", + "299 23546 001-842-369-3244x325 \n", + "\n", + "[152 rows x 9 columns]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "female_texans.fetch(format=\"frame\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "152" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "len(female_texans)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -1795,7 +3734,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -1804,39 +3743,485 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
\n", + "

date_of_birth

\n", + " \n", + "
\n", + "

home_address

\n", + " mailing street address\n", + "
\n", + "

home_city

\n", + " mailing address\n", + "
\n", + "

home_state

\n", + " US state acronym: e.g. OH\n", + "
\n", + "

home_zip

\n", + " zipcode e.g. 93979-4979\n", + "
\n", + "

home_phone

\n", + " e.g. 414.657.6883x0881\n", + "
8JacquelineColonF1996-02-2464635 Duncan PlaceSolisburghUT76301(983)027-5735x055
210PaulaPerezF2000-08-1517911 Frazier RoadsPort TashaUT21725405.906.1669
248RichardNobleM2003-02-057977 Adams Crossroad Suite 214Port CatherinelandUT34911458.117.5719
269VeronicaAndersonF1997-05-190043 Baker SpringsKristinatonUT04908(811)585-2197x666
\n", + " \n", + "

Total: 4

\n", + " " + ], + "text/plain": [ + "*student_id first_name last_name sex date_of_birth home_address home_city home_state home_zip home_phone \n", + "+------------+ +------------+ +-----------+ +-----+ +------------+ +------------+ +------------+ +------------+ +----------+ +------------+\n", + "8 Jacqueline Colon F 1996-02-24 64635 Duncan P Solisburgh UT 76301 (983)027-5735x\n", + "210 Paula Perez F 2000-08-15 17911 Frazier Port Tasha UT 21725 405.906.1669 \n", + "248 Richard Noble M 2003-02-05 7977 Adams Cro Port Catherine UT 34911 458.117.5719 \n", + "269 Veronica Anderson F 1997-05-19 0043 Baker Spr Kristinaton UT 04908 (811)585-2197x\n", + " (Total: 4)" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "utah_genz" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

first_name

\n", + " \n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
\n", + "

date_of_birth

\n", + " \n", + "
\n", + "

home_address

\n", + " mailing street address\n", + "
\n", + "

home_city

\n", + " mailing address\n", + "
\n", + "

home_state

\n", + " US state acronym: e.g. OH\n", + "
\n", + "

home_zip

\n", + " zipcode e.g. 93979-4979\n", + "
\n", + "

home_phone

\n", + " e.g. 414.657.6883x0881\n", + "
8JacquelineColonF1996-02-2464635 Duncan PlaceSolisburghUT76301(983)027-5735x055
210PaulaPerezF2000-08-1517911 Frazier RoadsPort TashaUT21725405.906.1669
248RichardNobleM2003-02-057977 Adams Crossroad Suite 214Port CatherinelandUT34911458.117.5719
269VeronicaAndersonF1997-05-190043 Baker SpringsKristinatonUT04908(811)585-2197x666
\n", + " \n", + "

Total: 4

\n", + " " + ], + "text/plain": [ + "*student_id first_name last_name sex date_of_birth home_address home_city home_state home_zip home_phone \n", + "+------------+ +------------+ +-----------+ +-----+ +------------+ +------------+ +------------+ +------------+ +----------+ +------------+\n", + "8 Jacqueline Colon F 1996-02-24 64635 Duncan P Solisburgh UT 76301 (983)027-5735x\n", + "210 Paula Perez F 2000-08-15 17911 Frazier Port Tasha UT 21725 405.906.1669 \n", + "248 Richard Noble M 2003-02-05 7977 Adams Cro Port Catherine UT 34911 458.117.5719 \n", + "269 Veronica Anderson F 1997-05-19 0043 Baker Spr Kristinaton UT 04908 (811)585-2197x\n", + " (Total: 4)" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "utah_genz = utah_genz.proj('last_name', 'home_city','home_state','sex')\n", "utah_genz" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'name': 'student',\n", + " 'engine': 'InnoDB',\n", + " 'version': 10,\n", + " 'row_format': 'Dynamic',\n", + " 'rows': 0,\n", + " 'avg_row_length': 0,\n", + " 'data_length': 16384,\n", + " 'max_data_length': 0,\n", + " 'index_length': 0,\n", + " 'data_free': 0,\n", + " 'auto_increment': None,\n", + " 'create_time': datetime.datetime(2020, 10, 27, 9, 45, 43),\n", + " 'update_time': None,\n", + " 'check_time': None,\n", + " 'collation': 'latin1_swedish_ci',\n", + " 'checksum': None,\n", + " 'create_options': '',\n", + " 'comment': ''}" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "for r in utah_genz:\n", - " print(r)" + "utah_genz.heading.table_status" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

student_id

\n", + " university-wide ID number\n", + "
\n", + "

last_name

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
\n", + "

home_city

\n", + " mailing address\n", + "
\n", + "

home_state

\n", + " US state acronym: e.g. OH\n", + "
8ColonFSolisburghUT
210PerezFPort TashaUT
248NobleMPort CatherinelandUT
269AndersonFKristinatonUT
\n", + " \n", + "

Total: 4

\n", + " " + ], + "text/plain": [ + "*student_id last_name sex home_city home_state \n", + "+------------+ +-----------+ +-----+ +------------+ +------------+\n", + "8 Colon F Solisburgh UT \n", + "210 Perez F Port Tasha UT \n", + "248 Noble M Port Catherine UT \n", + "269 Anderson F Kristinaton UT \n", + " (Total: 4)" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "utah_genz = utah_genz.proj('last_name', 'home_city','home_state','sex')\n", + "utah_genz" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['student_id', 'last_name', 'sex', 'home_city', 'home_state']" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "utah_genz.heading.non_blobs" + ] } ], "metadata": { @@ -1855,7 +4240,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.8.5" } }, "nbformat": 4, diff --git a/notebooks/Improvements.ipynb b/notebooks/Improvements.ipynb index d3106ab..8c52e69 100644 --- a/notebooks/Improvements.ipynb +++ b/notebooks/Improvements.ipynb @@ -1451,7 +1451,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.7" + "version": "3.8.5" } }, "nbformat": 4, diff --git a/notebooks/Update1.ipynb b/notebooks/Update1.ipynb new file mode 100644 index 0000000..2883d3e --- /dev/null +++ b/notebooks/Update1.ipynb @@ -0,0 +1,348 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# `update1`\n", + "## Updating values in a table" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In DataJoint, the principal way of replacing data is by `delete` and `insert`. This approach observes referential integrity constraints. \n", + "\n", + "In some cases, it becomes necessary to deliberately correct existing values. The `update1` method accomplishes this. The method should only be used to fix problems, and not as part of a regular workflow. When updating an entry, make sure that any information stored in dependent tables that depends on the update values is properly updated as well. \n", + "\n", + "Syntax:\n", + "\n", + "```python\n", + "table.update1(record)\n", + "```\n", + "Here `record` is a `dict` specifying the primary key values for identifying what record to update and the values that should be updated. The entry must already exist.\n", + "\n", + "## Example\n", + "Let's create the `Student` table and populate a few entries." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import datajoint as dj\n", + "schema = dj.schema('test_update')\n", + "\n", + "@schema\n", + "class Student(dj.Manual):\n", + " definition = \"\"\"\n", + " student_id : int\n", + " ---\n", + " full_name : varchar(100) # last_name, first_name middle_name\n", + " phone=\"\": varchar(20)\n", + " sex : enum('female', 'male')\n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "Student.insert1(dict(student_id=303, full_name=\"Rosen, Rose\", sex=\"female\"))\n", + "Student.insert1(dict(student_id=304, full_name=\"Rosen, Rose\", sex=\"male\", phone=\"(813)555-3744\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

student_id

\n", + " \n", + "
\n", + "

full_name

\n", + " last_name, first_name middle_name\n", + "
\n", + "

phone

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
303Rosen, Rosefemale
304Rosen, Rose(813)555-3744male
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*student_id full_name phone sex \n", + "+------------+ +------------+ +------------+ +--------+\n", + "303 Rosen, Rose female \n", + "304 Rosen, Rose (813)555-3744 male \n", + " (Total: 2)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Student()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now update some values. Note that you must specify the primary key and the entry must already exist." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n", + "

student_id

\n", + " \n", + "
\n", + "

full_name

\n", + " last_name, first_name middle_name\n", + "
\n", + "

phone

\n", + " \n", + "
\n", + "

sex

\n", + " \n", + "
303Rosen, Rose(813)555-7133female
304Ramesh, Henry(813)555-3744male
\n", + " \n", + "

Total: 2

\n", + " " + ], + "text/plain": [ + "*student_id full_name phone sex \n", + "+------------+ +------------+ +------------+ +--------+\n", + "303 Rosen, Rose (813)555-7133 female \n", + "304 Ramesh, Henry (813)555-3744 male \n", + " (Total: 2)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Student.update1(dict(student_id=303, phone=\"(813)555-7133\"))\n", + "Student.update1(dict(student_id=304, full_name=\"Ramesh, Henry\"))\n", + "Student()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If the entry does not exist or if the primary key value is not specified, `update1` raises errors:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "ename": "DataJointError", + "evalue": "Update entry must exist.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mDataJointError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mStudent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate1\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstudent_id\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m305\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mphone\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"(800)555-3377\"\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[0m", + "\u001b[0;32m~/dev/datajoint-python/datajoint/table.py\u001b[0m in \u001b[0;36mupdate1\u001b[0;34m(self, row)\u001b[0m\n\u001b[1;32m 237\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mrow\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprimary_key\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 238\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m \u001b[0;34m&\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 239\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Update entry must exist.'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 240\u001b[0m \u001b[0;31m# UPDATE query\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 241\u001b[0m \u001b[0mrow\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__make_placeholder\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrow\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitems\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprimary_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mDataJointError\u001b[0m: Update entry must exist." + ] + } + ], + "source": [ + "Student.update1(dict(student_id=305, phone=\"(800)555-3377\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "ename": "DataJointError", + "evalue": "The argument of update1 must supply all primary key values.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mDataJointError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mStudent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate1\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mphone\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"(800)555-3377\"\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[0m", + "\u001b[0;32m~/dev/datajoint-python/datajoint/table.py\u001b[0m in \u001b[0;36mupdate1\u001b[0;34m(self, row)\u001b[0m\n\u001b[1;32m 228\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'The argument of update1 must be dict-like.'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 229\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0missuperset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprimary_key\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[0;32m--> 230\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'The argument of update1 must supply all primary key values.'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 231\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 232\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Attribute `%s` not found.'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mk\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrow\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mheading\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnames\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[0;31mDataJointError\u001b[0m: The argument of update1 must supply all primary key values." + ] + } + ], + "source": [ + "Student.update1(dict(phone=\"(800)555-3377\"))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From ecb9b78faf5493cecd265a507a08b0c94874f116 Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Sat, 13 Mar 2021 11:08:40 -0600 Subject: [PATCH 11/11] add a notebook explaining QueryCache --- notebooks/Adapted-Quantities.ipynb | 239 +++++++++++++++++++++++++++++ notebooks/QueryCache.ipynb | 228 +++++++++++++++++++++++++++ 2 files changed, 467 insertions(+) create mode 100644 notebooks/Adapted-Quantities.ipynb create mode 100644 notebooks/QueryCache.ipynb diff --git a/notebooks/Adapted-Quantities.ipynb b/notebooks/Adapted-Quantities.ipynb new file mode 100644 index 0000000..83bd4de --- /dev/null +++ b/notebooks/Adapted-Quantities.ipynb @@ -0,0 +1,239 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Adapted Attribute Type for quantities\n", + "\n", + "**Purpose**: demonstrate using `dj.AttributeAdapter` for convenient storage of custom datatypes, e.g. objects from the quantities module." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's create a table with attribute `volume` storing values of type `mL` from the [`quantities`](https://pypi.org/project/quantities/) library." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.12.7\n" + ] + } + ], + "source": [ + "import datajoint as dj\n", + "print(dj.__version__)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# The following is necessary in DataJoint version 0.12.* \n", + "# while adapted types are in beta testing.\n", + "dj.errors._switch_adapted_types(True) " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import quantities as pq\n", + "\n", + "class Milliliter(dj.AttributeAdapter):\n", + " attribute_type = 'float'\n", + " \n", + " def put(self, obj: pq.Quantity) -> float:\n", + " assert isinstance(obj, pq.Quantity)\n", + " obj = obj.rescale(pq.mL)\n", + " return obj.item()\n", + "\n", + " def get(self, value) -> str:\n", + " return value * pq.mL\n", + "\n", + "mL = Milliliter()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then we need to define an adapter object that convert target objects into an attribute type that datajoint can already store. The class must subclass `dj.AttributeAdapter` and define the property `attribute_type`, and methods `get` and `put`. These methods translate the adapted data type `nx.Graph` into a representation that can be stored in datajoint, a `longblob` storing the edge list." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we can define a table that uses `graph` as its attribute type. These \"adapted types\" must be enclosed in angle brackets as in ``:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connecting dbadmin@dimitri-proj0.cda95qzjbnvs.us-east-1.rds.amazonaws.com:3306\n", + "Proceed to delete entire schema `test_quantities`? [yes, No]: yes\n" + ] + } + ], + "source": [ + "schema = dj.schema('test_quantities')\n", + "schema.drop() # drop previous contents\n", + "schema = dj.schema('test_quantities') # create de novo" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "@schema\n", + "class Quantity(dj.Manual):\n", + " definition = \"\"\"\n", + " quant_id : int\n", + " ---\n", + " volume : \n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "quant_id : int \n", + "---\n", + "volume : \n", + "\n" + ] + } + ], + "source": [ + "Quantity.describe();" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Now, populate the table with our example graphs and fetch them as objects\n", + "Inserting the graphs as objects" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "Quantity().insert([\n", + " (1, 2.3 * pq.mL),\n", + " (2, 3.5 * pq.mL)])" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([array(2.3) * mL, array(3.5) * mL], dtype=object)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "q = Quantity.fetch('volume')\n", + "q" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "d = (3.5 * pq.mL).dtype" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dtype('float64')" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "d" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/QueryCache.ipynb b/notebooks/QueryCache.ipynb new file mode 100644 index 0000000..2c26544 --- /dev/null +++ b/notebooks/QueryCache.ipynb @@ -0,0 +1,228 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Query Caching\n", + "\n", + "Query caching allows avoiding repeated queries to the database by caching the results locally for faster retrieval. \n", + "\n", + "To enable queries, set the query cache local path in `dj.config['query_cache']` and activate the query caching with `conn.set_query_cache(query_cache)` where `conn` is the connection object. \n", + "\n", + "A reference to the connection object is kept as a property of the schema or table objects, e.g. `schema.connection`. Alternatively, the function `dj.conn()` returns the currently active connection object. \n", + "\n", + "The `query_cache` argument is an aribtrary string serving to differentiate cache states; setting a new value will effectively start a new cache, triggering retrieval of new values once.\n", + "\n", + "Setting `query_cache=None` turns off query caching.\n", + "\n", + "While query caching is enabled, any `insert` or `delete` calls and any transactions are disabled and will raise an error. This ensures that stale data are not used for updating the database in violation of data integrity. \n", + "\n", + "To clear the cache, delete the contents of the folder specified in `dj.config['query_cahce']`.\n", + "\n", + "\n", + "## A complete example" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import datajoint as dj\n", + "import numpy as np\n", + "import os" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a table to store image data and populate it" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "schema = dj.schema('test_query_caching')\n", + "\n", + "@schema\n", + "class Image(dj.Manual):\n", + " definition = \"\"\"\n", + " image_number : int\n", + " ---\n", + " image : longblob\n", + " \"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "Image.insert1((1, np.random.randn(300,300)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Time query without caching." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "403 ms ± 72.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "r = (Image & 'image_number=1').fetch1('image')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Enable query caching and note that queries are sped up." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "dj.config['query_cache']=os.path.expanduser('~/tmp')\n", + "conn = dj.conn()\n", + "conn.set_query_cache('s0')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2.91 ms ± 57.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "r = (Image & 'image_number=1').fetch1('image')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Any attempts to insert or delete data will result in an error while query caching is on." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "ename": "DataJointError", + "evalue": "Only SELECT queries are allowed when query caching is on.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mDataJointError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mImage\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdelete\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[0m", + "\u001b[0;32m~/dev/datajoint-python/datajoint/table.py\u001b[0m in \u001b[0;36mdelete\u001b[0;34m(self, transaction, safemode)\u001b[0m\n\u001b[1;32m 384\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtransaction\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 385\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0min_transaction\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 386\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconnection\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstart_transaction\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[0m\u001b[1;32m 387\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 388\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0msafemode\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/datajoint-python/datajoint/connection.py\u001b[0m in \u001b[0;36mstart_transaction\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 333\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0min_transaction\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 334\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0merrors\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Nested connections are not supported.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 335\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'START TRANSACTION WITH CONSISTENT SNAPSHOT'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 336\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_in_transaction\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[1;32m 337\u001b[0m \u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minfo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Transaction started\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/dev/datajoint-python/datajoint/connection.py\u001b[0m in \u001b[0;36mquery\u001b[0;34m(self, query, args, as_dict, suppress_warnings, reconnect)\u001b[0m\n\u001b[1;32m 273\u001b[0m \u001b[0muse_query_cache\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbool\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_query_cache\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 274\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0muse_query_cache\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mr\"\\s*(SELECT|SHOW)\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mquery\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[0;32m--> 275\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0merrors\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDataJointError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Only SELECT queries are allowed when query caching is on.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 276\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0muse_query_cache\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 277\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'query_cache'\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[0;31mDataJointError\u001b[0m: Only SELECT queries are allowed when query caching is on." + ] + } + ], + "source": [ + "Image.delete()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Turn off query caching. Data manua" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Turn off query caching\n", + "conn.set_query_cache(None)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Deleting 1 rows from `test_query_caching`.`image`\n", + "Commit deletes? [yes, No]: yes\n", + "Deletes committed.\n" + ] + } + ], + "source": [ + "Image.delete()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}