{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Import a flat file into a SQLite database\n", "\n", "Importing a flatfile can be done with *pandas*. *pyensae* proposes a function which does so by guessing the schema over the first lines."]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/html": ["Plan\n", "
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["import pyensae\n", "from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### Mix SQLite and DataFrame"]}, {"cell_type": "markdown", "metadata": {}, "source": ["When a dataset is huge (~3Gb), it takes some time to load it into a DataFrame. It is difficult to look at it in any tool (Python, Excel, ...) One option I usually do is to load it a SQL server if you have one. If you do not, then [SQLite](http://www.sqlite.org/) is the best option. Let's see how it works with a custom datasets."]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": [" downloading of http://www.xavierdupre.fr/enseignement/complements/velib_vanves.zip to velib_vanves.zip\n", " unzipped velib_vanves.txt to .\\velib_vanves.txt\n"]}, {"data": {"text/plain": ["['.\\\\velib_vanves.txt']"]}, "execution_count": 3, "metadata": {}, "output_type": "execute_result"}], "source": ["import pyensae\n", "import pyensae.datasource\n", "pyensae.datasource.download_data(\"velib_vanves.zip\", website = \"xd\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["As this file is small (just an example), let's see how it looks like with a DataFrame."]}, {"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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
addressavailable_bike_standsavailable_bikesbankingbike_standsbonuscontract_namelast_updatelatlngnamenumberstatusidr
0 112 RUE VERCINGETORIX - 75014 PARIS 65 2 0 67 0 Paris 15/07/2013 15:00 48,83425925 2,313391647 14029 - GERGOVIE VERCINGETORIX 14029 OPEN 669
1 112 RUE VERCINGETORIX - 75014 PARIS 65 2 0 67 0 Paris 15/07/2013 15:05 48,83425925 2,313391647 14029 - GERGOVIE VERCINGETORIX 14029 OPEN 1898
\n", "

2 rows \u00d7 14 columns

\n", "
"], "text/plain": [" address available_bike_stands \\\n", "0 112 RUE VERCINGETORIX - 75014 PARIS 65 \n", "1 112 RUE VERCINGETORIX - 75014 PARIS 65 \n", "\n", " available_bikes banking bike_stands bonus contract_name \\\n", "0 2 0 67 0 Paris \n", "1 2 0 67 0 Paris \n", "\n", " last_update lat lng name \\\n", "0 15/07/2013 15:00 48,83425925 2,313391647 14029 - GERGOVIE VERCINGETORIX \n", "1 15/07/2013 15:05 48,83425925 2,313391647 14029 - GERGOVIE VERCINGETORIX \n", "\n", " number status idr \n", "0 14029 OPEN 669 \n", "1 14029 OPEN 1898 \n", "\n", "[2 rows x 14 columns]"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["import pandas\n", "df = pandas.read_csv(\"velib_vanves.txt\",sep=\"\\t\")\n", "df.head(n=2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Then we import it into a SQLite3 database. The following function automatically guesses the table schema."]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["processing file velib_vanves.txt\n", " TextFile: opening file velib_vanves.txt\n", " TextFile: closing file velib_vanves.txt\n", " swith to str ('address', (, 70)) value 112 RUE VERCINGETORIX - 75014 PARIS\n", " swith to str ('contract_name', (, 10)) value Paris\n", " swith to str ('last_update', (, 32)) value 15/07/2013 15:00\n", " swith to str ('lat', (, 22)) value 48,83425925\n", " swith to str ('lng', (, 22)) value 2,313391647\n", " swith to str ('name', (, 60)) value 14029 - GERGOVIE VERCINGETORIX\n", " swith to str ('status', (, 8)) value OPEN\n", " guess {0: ('address', (, 70)), 1: ('available_bike_stands', ), 2: ('available_bikes', ), 3: ('banking', ), 4: ('bike_stands', ), 5: ('bonus', ), 6: ('contract_name', (, 10)), 7: ('last_update', (, 32)), 8: ('lat', (, 22)), 9: ('lng', (, 22)), 10: ('name', (, 60)), 11: ('number', ), 12: ('status', (, 8)), 13: ('idr', )}\n", "columns {0: ('address', (, 70)), 1: ('available_bike_stands', ), 2: ('available_bikes', ), 3: ('banking', ), 4: ('bike_stands', ), 5: ('bonus', ), 6: ('contract_name', (, 10)), 7: ('last_update', (, 32)), 8: ('lat', (, 22)), 9: ('lng', (, 22)), 10: ('name', (, 60)), 11: ('number', ), 12: ('status', (, 8)), 13: ('idr', ), 14: ('key', , 'PRIMARYKEY', 'AUTOINCREMENT')}\n", "SQL 'CREATE TABLE velib_vanves(address TEXT,'\n", "' available_bike_stands INTEGER,'\n", "' available_bikes INTEGER,'\n", "' banking INTEGER,'\n", "' bike_stands INTEGER,'\n", "' bonus INTEGER,'\n", "' contract_name TEXT,'\n", "' last_update TEXT,'\n", "' lat TEXT,'\n", "' lng TEXT,'\n", "' name TEXT,'\n", "' number INTEGER,'\n", "' status TEXT,'\n", "' idr INTEGER,'\n", "' key INTEGER PRIMARY KEY AUTOINCREMENT);'\n", " TextFile: opening file velib_vanves.txt\n", " TextFile: closing file velib_vanves.txt\n", "9461 lines imported\n"]}], "source": ["from pyensae.sql import import_flatfile_into_database\n", "import_flatfile_into_database(\"velib_vanves.db3\", \"velib_vanves.txt\", add_key=\"key\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["We check the database exists:"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"data": {"text/plain": ["['pyensae_flat2db3.ipynb',\n", " 'pyensae_StockPrices.ipynb',\n", " 'pyensae_velib.ipynb',\n", " 'velib_vanves.db3',\n", " 'velib_vanves.txt',\n", " 'velib_vanves.zip']"]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}], "source": ["import os\n", "os.listdir(\".\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On Windows, you can use [SQLiteSpy](http://www.yunqa.de/delphi/doku.php/products/sqlitespy/index) to visualize the created table. We use [pymysintall](http://www.xavierdupre.fr/app/pymyinstall/helpsphinx/index.html) to download it."]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["SQLiteSpy, version 1.9.7\n", "download http://www.yunqa.de/delphi/lib/exe/fetch.php?hash=938481&media=http%3A%2F%2Fwww.yunqa.de%2Fdelphi%2Fdownloads%2FSQLiteSpy_1.9.7.zip\n", "len 1828282\n", " unzipped SQLiteSpy.exe to .\\SQLiteSpy.exe\n", " unzipped World.db3 to .\\World.db3\n"]}, {"data": {"text/plain": ["'.\\\\SQLiteSpy.exe'"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["try:\n", " from pymyinstall.installcustom import install_sqlitespy\n", " exe = install_sqlitespy()\n", "except:\n", " # we skip an exception\n", " # the website can be down...\n", " exe = None\n", "exe"]}, {"cell_type": "markdown", "metadata": {}, "source": ["We just need to run it (see [run_cmd](http://www.xavierdupre.fr/app/pyquickhelper/helpsphinx/pyquickhelper/loghelper/flog.html?highlight=run_cmd#loghelper.flog.run_cmd))."]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"data": {"text/plain": ["('', '')"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["if exe:\n", " from pyquickhelper import run_cmd\n", " run_cmd(\"SQLiteSpy.exe velib_vanves.db3\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["You should be able to see something like (on Windows):"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"image/png": "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\nPwgXy+0C493XAAAAAElFTkSuQmCC\n", "text/plain": [""]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["from pyquickhelper.helpgen import NbImage\n", "NbImage('img_nb_sqlitespy.png')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It is easier to use that tool to extract a sample of the data. Once it is ready, you can execute the SQL query in Python and converts the results into a DataFrame. The following code extracts a random sample from the original sets."]}, {"cell_type": "code", "execution_count": 9, "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", "
keylast_updateavailable_bike_standsavailable_bikes
0 24 15/07/2013 16:55 66 1
1 26 15/07/2013 17:05 66 1
2 178 16/07/2013 05:45 49 18
3 220 16/07/2013 09:15 63 4
4 342 16/07/2013 19:25 61 6
\n", "

5 rows \u00d7 4 columns

\n", "
"], "text/plain": [" key last_update available_bike_stands available_bikes\n", "0 24 15/07/2013 16:55 66 1\n", "1 26 15/07/2013 17:05 66 1\n", "2 178 16/07/2013 05:45 49 18\n", "3 220 16/07/2013 09:15 63 4\n", "4 342 16/07/2013 19:25 61 6\n", "\n", "[5 rows x 4 columns]"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["sql = \"\"\"SELECT * FROM velib_vanves WHERE key IN ({0})\"\"\"\n", "\n", "import random\n", "from pyquickhelper.loghelper import noLOG\n", "from pyensae.sql import Database\n", "db = Database(\"velib_vanves.db3\", LOG = noLOG)\n", "db.connect()\n", "mx = db.execute_view(\"SELECT MAX(key) FROM velib_vanves\")[0][0]\n", "rnd_ids = [ random.randint(1,mx) for i in range(0,100) ] # liste de 100 id al\u00e9atoires\n", "strids = \",\".join( str(_) for _ in rnd_ids )\n", "res = db.execute_view(sql.format (strids))\n", "df = db.to_df(sql.format (strids))\n", "db.close()\n", "df.head()[[\"key\",\"last_update\",\"available_bike_stands\",\"available_bikes\"]]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["

Memory Dump

\n", "\n", "Once you have a big dataset available in text format, it takes some time to load into memory and you need to do that every time you need it again after you closed your python instance."]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"data": {"text/plain": ["474285221"]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["with open(\"temp_big_file.txt\",\"w\") as f :\n", " f.write(\"c1\\tc2\\tc3\\n\")\n", " for i in range(0,10000000):\n", " x = [ i, random.random(), random.random() ]\n", " s = [ str(_) for _ in x ]\n", " f.write( \"\\t\".join(s) + \"\\n\" )\n", "os.stat(\"temp_big_file.txt\").st_size "]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["duration (s) 8.405750774129501\n"]}], "source": ["import pandas,time\n", "t = time.perf_counter()\n", "df = pandas.read_csv(\"temp_big_file.txt\",sep=\"\\t\")\n", "print(\"duration (s)\",time.perf_counter()-t)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It is slow considering that many datasets contain many more features. But we can speed it up by doing a kind of memory dump with [to_pickle](http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.to_pickle.html)."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["duration (s) 2.2846547239112738\n"]}], "source": ["t = time.perf_counter()\n", "df.to_pickle(\"temp_big_file.bin\")\n", "print(\"duration (s)\",time.perf_counter()-t)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["And we reload it with [read_pickle](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.pickle.read_pickle.html):"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["duration (s) 0.7951709542244885\n"]}], "source": ["t = time.perf_counter()\n", "df = pandas.read_pickle(\"temp_big_file.bin\")\n", "print(\"duration (s)\",time.perf_counter()-t)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It is 10 times faster and usually smaller on the disk."]}, {"cell_type": "code", "execution_count": 14, "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.2"}}, "nbformat": 4, "nbformat_minor": 2}