diff --git a/compareDBs.ipynb b/compareDBs.ipynb index 5fec7e5..7082ef4 100644 --- a/compareDBs.ipynb +++ b/compareDBs.ipynb @@ -47,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "ab6c6c81-6ac1-4668-a79b-a9a0341fb35a", "metadata": { "tags": [] @@ -59,13 +59,16 @@ "False" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import configparser\n", + "\n", + "# import pymongo\n", + "import io\n", "import time\n", "import timeit\n", "from datetime import datetime\n", @@ -75,8 +78,6 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import pandas as pd\n", - "\n", - "# import pymongo\n", "from clickhouse_driver import Client\n", "from dotenv import load_dotenv\n", "from minio import Minio\n", @@ -89,7 +90,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 2, "id": "55c3cd57-0996-4723-beb5-8f3196c96009", "metadata": { "tags": [] @@ -102,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 3, "id": "968403e3-2e5e-4834-b969-be4600e2963a", "metadata": { "tags": [] @@ -137,7 +138,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 4, "id": "3634a4ec-04c2-4f1e-8659-5d22eb17a254", "metadata": {}, "outputs": [ @@ -254,7 +255,7 @@ "4 1.065975 1.066055 1.065830 1.066055 50 " ] }, - "execution_count": 14, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -315,46 +316,21 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 22, "id": "c3202bbb-2655-45b2-b166-9f45a3ef854c", "metadata": { "tags": [] }, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "Failed to connect to 192.168.1.142:9000\n", - "Traceback (most recent call last):\n", - " File \"/home/sandman/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/connection.py\", line 395, in connect\n", - " return self._init_connection(host, port)\n", - " File \"/home/sandman/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/connection.py\", line 325, in _init_connection\n", - " self.socket = self._create_socket(host, port)\n", - " File \"/home/sandman/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/connection.py\", line 297, in _create_socket\n", - " raise err\n", - " File \"/home/sandman/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/connection.py\", line 288, in _create_socket\n", - " sock.connect(sa)\n", - "TimeoutError: timed out\n" - ] - }, - { - "ename": "SocketTimeoutError", - "evalue": "Code: 209. (192.168.1.142:9000)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mSocketTimeoutError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[15], line 44\u001b[0m\n\u001b[1;32m 40\u001b[0m client\u001b[38;5;241m.\u001b[39mdisconnect()\n\u001b[1;32m 41\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m dfQuery\n\u001b[0;32m---> 44\u001b[0m \u001b[43mcHouseCreateDb\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdbname\u001b[49m\u001b[43m)\u001b[49m\n", - "Cell \u001b[0;32mIn[15], line 17\u001b[0m, in \u001b[0;36mcHouseCreateDb\u001b[0;34m(databasename)\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcHouseCreateDb\u001b[39m(databasename):\n\u001b[1;32m 16\u001b[0m client \u001b[38;5;241m=\u001b[39m cHouseConnect()\n\u001b[0;32m---> 17\u001b[0m \u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 18\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mCREATE TABLE IF NOT EXISTS \u001b[39;49m\u001b[38;5;132;43;01m{}\u001b[39;49;00m\u001b[38;5;124;43m (id UInt32,\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 19\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfrom DateTime, at UInt64, to DateTime, open Float64,\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 20\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mclose Float64, min Float64, max Float64, volume UInt32)\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\n\u001b[1;32m 21\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mENGINE MergeTree ORDER BY to\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mformat\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdatabasename\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 22\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 23\u001b[0m client\u001b[38;5;241m.\u001b[39mdisconnect()\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mDatabase created\u001b[39m\u001b[38;5;124m\"\u001b[39m\n", - "File \u001b[0;32m~/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/client.py:361\u001b[0m, in \u001b[0;36mClient.execute\u001b[0;34m(self, query, params, with_column_types, external_tables, query_id, settings, types_check, columnar)\u001b[0m\n\u001b[1;32m 318\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 319\u001b[0m \u001b[38;5;124;03mExecutes query.\u001b[39;00m\n\u001b[1;32m 320\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 356\u001b[0m \u001b[38;5;124;03m and types.\u001b[39;00m\n\u001b[1;32m 357\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 359\u001b[0m start_time \u001b[38;5;241m=\u001b[39m time()\n\u001b[0;32m--> 361\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdisconnect_on_error(query, settings):\n\u001b[1;32m 362\u001b[0m \u001b[38;5;66;03m# INSERT queries can use list/tuple/generator of list/tuples/dicts.\u001b[39;00m\n\u001b[1;32m 363\u001b[0m \u001b[38;5;66;03m# For SELECT parameters can be passed in only in dict right now.\u001b[39;00m\n\u001b[1;32m 364\u001b[0m is_insert \u001b[38;5;241m=\u001b[39m \u001b[38;5;28misinstance\u001b[39m(params, (\u001b[38;5;28mlist\u001b[39m, \u001b[38;5;28mtuple\u001b[39m, types\u001b[38;5;241m.\u001b[39mGeneratorType))\n\u001b[1;32m 366\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m is_insert:\n", - "File \u001b[0;32m~/dev/anaconda3/lib/python3.10/contextlib.py:135\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__enter__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 133\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkwds, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunc\n\u001b[1;32m 134\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 135\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[1;32m 137\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgenerator didn\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mt yield\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n", - "File \u001b[0;32m~/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/client.py:305\u001b[0m, in \u001b[0;36mClient.disconnect_on_error\u001b[0;34m(self, query, settings)\u001b[0m\n\u001b[1;32m 302\u001b[0m \u001b[38;5;129m@contextmanager\u001b[39m\n\u001b[1;32m 303\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdisconnect_on_error\u001b[39m(\u001b[38;5;28mself\u001b[39m, query, settings):\n\u001b[1;32m 304\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 305\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mestablish_connection\u001b[49m\u001b[43m(\u001b[49m\u001b[43msettings\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 307\u001b[0m \u001b[38;5;28;01myield\u001b[39;00m\n\u001b[1;32m 309\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtrack_current_database(query)\n", - "File \u001b[0;32m~/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/client.py:292\u001b[0m, in \u001b[0;36mClient.establish_connection\u001b[0;34m(self, settings)\u001b[0m\n\u001b[1;32m 290\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconnection \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_connection()\n\u001b[1;32m 291\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmake_query_settings(settings)\n\u001b[0;32m--> 292\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconnection\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mforce_connect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 293\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlast_query \u001b[38;5;241m=\u001b[39m QueryInfo()\n\u001b[1;32m 295\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (errors\u001b[38;5;241m.\u001b[39mSocketTimeoutError, errors\u001b[38;5;241m.\u001b[39mNetworkError):\n", - "File \u001b[0;32m~/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/connection.py:254\u001b[0m, in \u001b[0;36mConnection.force_connect\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 251\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcheck_query_execution()\n\u001b[1;32m 253\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mconnected:\n\u001b[0;32m--> 254\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 256\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mping():\n\u001b[1;32m 257\u001b[0m logger\u001b[38;5;241m.\u001b[39mwarning(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mConnection was closed, reconnecting.\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", - "File \u001b[0;32m~/dev/pipenv/lib/python3.10/site-packages/clickhouse_driver/connection.py:416\u001b[0m, in \u001b[0;36mConnection.connect\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 413\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhosts\u001b[38;5;241m.\u001b[39mrotate(\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m)\n\u001b[1;32m 415\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m err \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 416\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m err\n", - "\u001b[0;31mSocketTimeoutError\u001b[0m: Code: 209. (192.168.1.142:9000)" - ] + "data": { + "text/plain": [ + "'Database created'" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -406,7 +382,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 23, "id": "cc4865b3-a1bc-4a35-9624-15334754b3a1", "metadata": {}, "outputs": [], @@ -420,7 +396,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 24, "id": "1fac82c1-2d04-44ef-893a-dc13b755e6d8", "metadata": {}, "outputs": [], @@ -434,7 +410,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 25, "id": "597ae7bd-2eea-44d7-b379-f0eb7e745c15", "metadata": { "tags": [] @@ -553,7 +529,7 @@ "4 1.066080 1.066025 1.066025 1.066110 57 " ] }, - "execution_count": 49, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -564,7 +540,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 26, "id": "86794e47-611f-4ca8-a7e8-07e71afafe67", "metadata": { "tags": [] @@ -574,7 +550,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "5.175396532999002\n" + "10.64297915700081\n" ] } ], @@ -584,7 +560,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 27, "id": "e7926062-8e84-4d3f-90a9-32807ce4f3d4", "metadata": { "tags": [] @@ -594,7 +570,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "6.163630739996734\n" + "6.190685558998666\n" ] } ], @@ -604,7 +580,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 28, "id": "8faa5683-a204-461d-80c3-67644aa714ce", "metadata": { "tags": [] @@ -614,8 +590,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 1.15 s, sys: 216 ms, total: 1.36 s\n", - "Wall time: 5.24 s\n" + "CPU times: user 2.21 s, sys: 383 ms, total: 2.6 s\n", + "Wall time: 10.7 s\n" ] } ], @@ -729,17 +705,19 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 7, "id": "16cd8eb7-333d-43fd-88e0-ee983645d3fd", "metadata": {}, "outputs": [ { - "ename": "SyntaxError", - "evalue": "invalid syntax. Perhaps you forgot a comma? (1520588424.py, line 4)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m Cell \u001b[0;32mIn[23], line 4\u001b[0;36m\u001b[0m\n\u001b[0;31m \"postgresql+psycopg2://{}:{}@{}:5432/{}\".format(\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax. Perhaps you forgot a comma?\n" - ] + "data": { + "text/plain": [ + "Engine(postgresql+psycopg2://postgres:***@192.168.1.133:5432/postgres)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ @@ -767,7 +745,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 18, "id": "be31f3a0-b7ed-48e6-9b65-dc16319fb8d1", "metadata": {}, "outputs": [], @@ -776,48 +754,97 @@ "def psqlCreateTables(databaseName):\n", " engine = psqlConnect()\n", " df.head(0).to_sql(databaseName, engine, if_exists=\"replace\", index=False)\n", + " # Write\n", + " conn = engine.raw_connection()\n", + " cur = conn.cursor()\n", + " output = io.StringIO()\n", + " df.to_csv(output, sep=\"\\t\", header=False, index=False)\n", + " output.seek(0)\n", + " contents = output.getvalue()\n", + "\n", + " cur.copy_from(output, \"comparedbs\") # , null=\"\") # null values become ''\n", + " conn.commit()\n", + " cur.close()\n", + " conn.close()\n", " # disconnect()\n", " return 0\n", "\n", "\n", - "psqlCreateTables(dbname)\n", + "# funcao read sql\n", + "def psqlReadTables():\n", + " engine = psqlConnect()\n", + " df = pd.read_sql_query('select * from \"comparedbs\"', con=engine)\n", + " return df\n", + "\n", + "\n", "# testar função" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 19, + "id": "98cc9360-4b84-43e4-b23b-b32d0c50c3b9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Insert to db and benchmark time\n", + "start = timeit.default_timer()\n", + "psqlCreateTables(dbname)\n", + "stop = timeit.default_timer()\n", + "psql_write_execution_time = stop - start" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "82e1b44e-35af-403f-9936-5e1561fd5abf", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "start = timeit.default_timer()\n", + "psqlReadTables()\n", + "stop = timeit.default_timer()\n", + "psql_read_execution_time = stop - start" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "id": "a7883c4d-4609-4380-8a45-246b7ca2f9c5", "metadata": { "tags": [] }, "outputs": [ { - "ename": "AttributeError", - "evalue": "'int' object has no attribute 'raw_connection'", + "ename": "NameError", + "evalue": "name 'engine' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "File \u001b[0;32m:2\u001b[0m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'int' object has no attribute 'raw_connection'" + "\u001b[0;31mNameError\u001b[0m: name 'engine' is not defined" ] } ], "source": [ - "%%time\n", - "# Write\n", - "conn = engine.raw_connection()\n", - "cur = conn.cursor()\n", - "output = io.StringIO()\n", - "df.to_csv(output, sep=\"\\t\", header=False, index=False)\n", - "output.seek(0)\n", - "contents = output.getvalue()\n", + "# %%time\n", + "# # Write\n", + "# conn = engine.raw_connection()\n", + "# cur = conn.cursor()\n", + "# output = io.StringIO()\n", + "# df.to_csv(output, sep=\"\\t\", header=False, index=False)\n", + "# output.seek(0)\n", + "# contents = output.getvalue()\n", "\n", - "cur.copy_from(output, \"comparedbs\") # , null=\"\") # null values become ''\n", - "conn.commit()\n", - "cur.close()\n", - "conn.close()" + "# cur.copy_from(output, \"comparedbs\") # , null=\"\") # null values become ''\n", + "# conn.commit()\n", + "# cur.close()\n", + "# conn.close()" ] }, { @@ -1266,7 +1293,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 37, "id": "a9740731-6077-4bf1-bb65-b4c4225ac79b", "metadata": { "tags": [] @@ -1274,7 +1301,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGwCAYAAACHJU4LAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAArPklEQVR4nO3de3RTZb7/8U9a2pRLm0JtaYEg0HK/CSjYqVDLRUBBEFQOg3KRkVFA1MrVc0SRweJ4UIRhgEG56IioKOjgAUTugmBpBUW5C9JxisxB6BVCaffvD3/kWFu1hLb7oX2/1spaZGdn55vMcvU9O08Sh2VZlgAAAAzkZ/cAAAAAv4RQAQAAxiJUAACAsQgVAABgLEIFAAAYi1ABAADGIlQAAICxqtg9wNUoKCjQv/71LwUHB8vhcNg9DgAAKAHLspSVlaU6derIz+/Xz5lc06Hyr3/9S2632+4xAACAD9LS0lSvXr1f3eeaDpXg4GBJPz7RkJAQm6cBAAAlkZmZKbfb7f07/muu6VC5/HZPSEgIoQIAwDWmJMs2WEwLAACMRagAAABjESoAAMBY1/QalZLKz89XXl6e3WNUCAEBAfL397d7DABAJVGhQ8WyLJ06dUrnzp2ze5QKJTQ0VJGRkXx3DQCgzFXoULkcKREREapWrRp/WK+SZVnKzc3V6dOnJUlRUVE2TwQAqOgqbKjk5+d7IyUsLMzucSqMqlWrSpJOnz6tiIgI3gYCAJSpCruY9vKalGrVqtk8ScVz+TVl3Q8AoKxV2FC5jLd7Sh+vKQCgvFT4UAEAANcuQgUAABirwi6m/TUNJn9Ybo91YuYd5fZYV2v48OE6d+6cVq9ebfcoAABI4oyKkYYPHy6HwyGHw6GAgAA1bNhQEydO1IULF+weDQCAclUpz6hcC3r16qUlS5YoLy9PKSkpGjZsmBwOh55//nm7RwMAoNxwRsVQTqdTkZGRcrvd6t+/v7p3764NGzZIkgoKCpSUlKSGDRuqatWqatu2rVauXOm9b35+vkaOHOm9vWnTpnr55ZcLHT8/P1+JiYkKDQ1VWFiYJk6cKMuyyvU5AgDwWzijcg3Yv3+/du7cqeuvv16SlJSUpL///e9asGCBGjdurG3btum+++5TeHi44uPjVVBQoHr16umdd95RWFiYdu7cqVGjRikqKkr33nuvJGnWrFlaunSpFi9erObNm2vWrFlatWqVunbtaudTBQp7xmX3BACeybD14QkVQ61Zs0Y1atTQpUuX5PF45Ofnp7/85S/yeDx67rnn9PHHHys2NlaS1KhRI33yySdauHCh4uPjFRAQoGnTpnmP1bBhQ3366ad6++23vaEye/ZsTZkyRQMGDJAkLViwQOvXry//JwoAwK8gVAyVkJCg+fPnKycnRy+99JKqVKmigQMH6quvvlJubq569OhRaP+LFy+qXbt23uvz5s3T4sWLdfLkSZ0/f14XL17UDTfcIEnKyMhQenq6OnXq5N2/SpUquvHGG3n7BwBgFELFUNWrV1dMTIwkafHixWrbtq1effVVtWrVSpL04Ycfqm7duoXu43Q6JUkrVqzQ+PHjNWvWLMXGxio4OFgvvPCCdu/eXb5PAgCAq0SoXAP8/Pz05JNPKjExUYcPH5bT6dTJkycVHx9f7P47duzQ7373O40ePdq77dixY95/u1wuRUVFaffu3erSpYsk6dKlS0pJSVH79u3L9skAAHAFbP/Uz3fffaf77rtPYWFhqlq1qlq3bq09e/bYPZZx7rnnHvn7+2vhwoUaP368Hn/8cS1btkzHjh1Tamqq5s6dq2XLlkmSGjdurD179mj9+vU6fPiwnnrqKSUnJxc63qOPPqqZM2dq9erVOnjwoEaPHq1z587Z8MwAAPhltp5ROXv2rOLi4pSQkKC1a9cqPDxcR44cUc2aNcv0ca+lb4u9rEqVKho7dqz+/Oc/6/jx4woPD1dSUpK++eYbhYaGqn379nryySclSX/84x/1+eefa9CgQXI4HBo8eLBGjx6ttWvXeo/3xBNPKD09XcOGDZOfn58eeOAB3XXXXcrIsHd1NwAAP+WwbFw9OXnyZO3YsUPbt2/36f6ZmZlyuVzKyMhQSEhIodsuXLig48ePq2HDhgoKCiqNcfH/8dqi3PDxZMB+ZfDx5F/7+/1ztr7188EHH+jGG2/UPffco4iICLVr106LFi36xf09Ho8yMzMLXQAAQMVla6h88803mj9/vho3bqz169fr4Ycf1rhx47xrLX4uKSlJLpfLe3G73eU8MQAAKE+2hkpBQYHat2+v5557Tu3atdOoUaP04IMPasGCBcXuP2XKFGVkZHgvaWlp5TwxAAAoT7aGSlRUlFq0aFFoW/PmzXXy5Mli93c6nQoJCSl0AQAAFZetoRIXF6dDhw4V2nb48GHvb9oAAIDKzdZQefzxx7Vr1y4999xzOnr0qJYvX66//e1vGjNmjJ1jAQAAQ9gaKjfddJNWrVqlN998U61atdL06dM1e/ZsDRkyxM6xAACAIWz/Cv0+ffqoT58+do8BAAAMZPtX6KPsNGjQQLNnz7Z7DAAAfGb7GRVblOe3XV7hN/otWLBAEyZM0NmzZ1Wlyo//82RnZ6tmzZqKi4vTli1bvPtu2bJFCQkJOnr0qKKjo4scKzk5WdWrV/dedzgcWrVqlfr37+/TUwEAoLxxRsUwCQkJys7OLvTDjNu3b1dkZKR2796tCxcueLdv3rxZ9evXLxIpFy9elCSFh4erWrVq5TM4AABlgFAxTNOmTRUVFVXkzEm/fv3UsGFD7dq1q9D2hIQEDR8+XP3799eMGTNUp04dNW3aVFLht34aNGggSbrrrrvkcDi81yXp/fffV/v27RUUFKRGjRpp2rRpunTpUlk/VQAAfhOhYqCEhARt3rzZe33z5s269dZbFR8f791+/vx57d69WwkJCZKkjRs36tChQ9qwYYPWrFlT5JjJycmSpCVLlig9Pd17ffv27Ro6dKgeffRRff3111q4cKGWLl2qGTNmlPXTBADgNxEqBkpISNCOHTt06dIlZWVl6fPPP1d8fLy6dOniPdPy6aefyuPxeEOlevXqeuWVV9SyZUu1bNmyyDHDw8MlSaGhoYqMjPRenzZtmiZPnqxhw4apUaNG6tGjh6ZPn66FCxeWz5MFAOBXVM7FtIa79dZblZOTo+TkZJ09e1ZNmjRReHi44uPjNWLECF24cEFbtmxRo0aNVL9+fUlS69atFRgYeMWPtW/fPu3YsaPQGZT8/HxduHBBubm5rHEBANiKUDFQTEyM6tWrp82bN+vs2bOKj4+XJNWpU0dut1s7d+7U5s2b1bVrV+99fvrpniuRnZ2tadOmacCAAUVuCwoK8u0JAABQSggVQyUkJGjLli06e/asJkyY4N3epUsXrV27Vp999pkefvjhKzpmQECA8vPzC21r3769Dh06pJiYmFKZGwCA0kSoGCohIUFjxoxRXl6e94yKJMXHx2vs2LG6ePGid31KSTVo0EAbN25UXFycnE6natasqalTp6pPnz6qX7++7r77bvn5+Wnfvn3av3+//vSnP5X20wIA4IqwmNZQCQkJOn/+vGJiYlS7dm3v9vj4eGVlZXk/xnwlZs2apQ0bNsjtdqtdu3aSpJ49e2rNmjX66KOPdNNNN+nmm2/WSy+9xC9YAwCM4LAsy7J7CF9lZmbK5XIpIyNDISEhhW67cOGCjh8/roYNG7LWopTx2qLclOe3SAMo3hV+w3pJ/Nrf75/jjAoAADAWoQIAAIxFqAAAAGMRKgAAwFgVPlSu4bXCxuI1BQCUlwobKgEBAZKk3NxcmyepeC6/ppdfYwAAykqF/cI3f39/hYaG6vTp05KkatWqyeFw2DzVtc2yLOXm5ur06dMKDQ2Vv7+/3SMBACq4ChsqkhQZGSlJ3lhB6bj8C8wAAJS1Ch0qDodDUVFRioiIUF5ent3jVAgBAQGcSQEAlJsKHSqX+fv788cVAIBrUIVdTAsAAK59hAoAADAWoQIAAIxFqAAAAGMRKgAAwFiECgAAMBahAgAAjEWoAAAAYxEqAADAWIQKAAAwFqECAACMRagAAABjESoAAMBYhAoAADAWoQIAAIxFqAAAAGMRKgAAwFiECgAAMFYVuwcwWYPJH9o9AlCpnQiyewIAduOMCgAAMBahAgAAjEWoAAAAYxEqAADAWIQKAAAwFqECAACMZWuoPPPMM3I4HIUuzZo1s3MkAABgENu/R6Vly5b6+OOPvderVLF9JAAAYAjbq6BKlSqKjIws0b4ej0cej8d7PTMzs6zGAgAABrB9jcqRI0dUp04dNWrUSEOGDNHJkyd/cd+kpCS5XC7vxe12l+OkAACgvNkaKp06ddLSpUu1bt06zZ8/X8ePH1fnzp2VlZVV7P5TpkxRRkaG95KWllbOEwMAgPJk61s/vXv39v67TZs26tSpk66//nq9/fbbGjlyZJH9nU6nnE5neY4IAABsZPtbPz8VGhqqJk2a6OjRo3aPAgAADGBUqGRnZ+vYsWOKioqyexQAAGAAW0Nl/Pjx2rp1q06cOKGdO3fqrrvukr+/vwYPHmznWAAAwBC2rlH55z//qcGDB+vMmTMKDw/XLbfcol27dik8PNzOsQAAgCFsDZUVK1bY+fAAAMBwRq1RAQAA+ClCBQAAGItQAQAAxiJUAACAsQgVAABgLEIFAAAYi1ABAADGIlQAAICxCBUAAGAsQgUAABiLUAEAAMYiVAAAgLEIFQAAYCxCBQAAGItQAQAAxiJUAACAsQgVAABgLEIFAAAYi1ABAADGIlQAAICxCBUAAGAsQgUAABiLUAEAAMYiVAAAgLEIFQAAYCxCBQAAGItQAQAAxiJUAACAsQgVAABgLEIFAAAYi1ABAADGIlQAAICxCBUAAGAsQgUAABiLUAEAAMYiVAAAgLEIFQAAYCxCBQAAGItQAQAAxiJUAACAsQgVAABgLEIFAAAYi1ABAADGIlQAAICxCBUAAGAsQgUAABjLmFCZOXOmHA6HHnvsMbtHAQAAhjAiVJKTk7Vw4UK1adPG7lEAAIBBbA+V7OxsDRkyRIsWLVLNmjV/dV+Px6PMzMxCFwAAUHHZHipjxozRHXfcoe7du//mvklJSXK5XN6L2+0uhwkBAIBdbA2VFStWKDU1VUlJSSXaf8qUKcrIyPBe0tLSynhCAABgpyp2PXBaWpoeffRRbdiwQUFBQSW6j9PplNPpLOPJAACAKWwLlZSUFJ0+fVrt27f3bsvPz9e2bdv0l7/8RR6PR/7+/naNBwAADGBbqHTr1k1ffvlloW0jRoxQs2bNNGnSJCIFAADYFyrBwcFq1apVoW3Vq1dXWFhYke0AAKBysv1TPwAAAL/EtjMqxdmyZYvdIwAAAINwRgUAABiLUAEAAMYiVAAAgLEIFQAAYCxCBQAAGItQAQAAxiJUAACAsQgVAABgLEIFAAAYi1ABAADG8ilUzp8/r9zcXO/1b7/9VrNnz9ZHH31UaoMBAAD4FCr9+vXTa6+9Jkk6d+6cOnXqpFmzZqlfv36aP39+qQ4IAAAqL59CJTU1VZ07d5YkrVy5UrVr19a3336r1157TXPmzCnVAQEAQOXlU6jk5uYqODhYkvTRRx9pwIAB8vPz080336xvv/22VAcEAACVl0+hEhMTo9WrVystLU3r16/XbbfdJkk6ffq0QkJCSnVAAABQefkUKlOnTtX48ePVoEEDderUSbGxsZJ+PLvSrl27Uh0QAABUXlV8udPdd9+tW265Renp6Wrbtq13e7du3XTXXXeV2nAAAKBy8ylUJCkyMlKRkZGFtnXs2PGqBwIAALisxKEyYMCAEh/0vffe82kYAACAnyrxGhWXy+W9hISEaOPGjdqzZ4/39pSUFG3cuFEul6tMBgUAAJVPic+oLFmyxPvvSZMm6d5779WCBQvk7+8vScrPz9fo0aP51A8AACg1Pn3qZ/HixRo/frw3UiTJ399fiYmJWrx4cakNBwAAKjefQuXSpUs6ePBgke0HDx5UQUHBVQ8FAAAg+fipnxEjRmjkyJE6duyY95M+u3fv1syZMzVixIhSHRAAAFRePoXKf//3fysyMlKzZs1Senq6JCkqKkoTJkzQE088UaoDAgCAysunUPHz89PEiRM1ceJEZWZmShKLaAEAQKnz+QvfLiNQAABAWfFpMe3333+v+++/X3Xq1FGVKlXk7+9f6AIAAFAafDqjMnz4cJ08eVJPPfWUoqKi5HA4SnsuAAAA30Llk08+0fbt23XDDTeU8jgAAAD/x6e3ftxutyzLKu1ZAAAACvEpVGbPnq3JkyfrxIkTpTwOAADA//HprZ9BgwYpNzdX0dHRqlatmgICAgrd/sMPP5TKcAAAoHLzKVRmz55dymMAAAAU5VOoDBs2rLTnAAAAKMLnL3zLz8/X6tWrdeDAAUlSy5Ytdeedd/I9KgAAoNT4FCpHjx7V7bffru+++05NmzaVJCUlJcntduvDDz9UdHR0qQ4JAAAqJ58+9TNu3DhFR0crLS1NqampSk1N1cmTJ9WwYUONGzeutGcEAACVlE9nVLZu3apdu3apVq1a3m1hYWGaOXOm4uLiSm04AABQufl0RsXpdCorK6vI9uzsbAUGBl71UAAAAJKPodKnTx+NGjVKu3fvlmVZsixLu3bt0kMPPaQ777yztGcEAACVlE+hMmfOHEVHRys2NlZBQUEKCgpSXFycYmJi9PLLL5f2jAAAoJLyaY1KaGio3n//fR09etT78eTmzZsrJiamVIcDAACVm8/foyJJMTExxAkAACgzPr31M3DgQD3//PNFtv/5z3/WPffcc9VDAQAASD6GyrZt23T77bcX2d67d29t27btqocCAACQfAyVX/oYckBAgDIzM0t8nPnz56tNmzYKCQlRSEiIYmNjtXbtWl9GAgAAFZBPodK6dWu99dZbRbavWLFCLVq0KPFx6tWrp5kzZyolJUV79uxR165d1a9fP3311Ve+jAUAACoYnxbTPvXUUxowYICOHTumrl27SpI2btyoN998U++8806Jj9O3b99C12fMmKH58+dr165datmyZZH9PR6PPB6P9/qVnL0BAADXHp/OqPTt21erV6/W0aNHNXr0aD3xxBP65z//qY8//lj9+/f3aZD8/HytWLFCOTk5io2NLXafpKQkuVwu78Xtdvv0WAAA4NrgsCzL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", + "image/png": "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tgPXwKFhZ/v27eaQmCQlJiZKkvr06aN58+Zp+PDhys/P14ABA5Sdna02bdpo5cqVpb6QhQsXavDgwerQoYNcXFzUs2dPzZgx44bvCwAAN6vY2FitW7dOp0+f1rBhw8z2du3a6euvv9Y333yj55577rr6dHNzU3Fxcam2Zs2aad++fapdu7Zd6r5WDg079913nwzDuOJym82mcePGady4cVdcJygoSIsWLaqI8gAAuCXExsZq0KBBKioqMkd2JCkmJkaDBw9WYWFhqcGJa1GzZk0lJyerdevW8vDwUOXKlTVmzBh17dpV1atX10MPPSQXFxft2rVLu3fv1uuvv27v3TI57ZwdAABwY8TGxurcuXOqXbt2qVu+xMTE6MyZM+Yl6tdjypQpWrNmjSIiItS0aVNJUnx8vFasWKHVq1fr7rvv1j333KNp06apRo0adt2f37MZfzS0covIzc1VQECAcnJyuAwdQJnUHPmlo0vAbxye2OWGft758+d16NAhRUZGVujck1vRH3231/r7zcgOAACwNMIOAACwNMIOAACwNMIOAACwNMIOAAB2wjU/9meP75SwAwBAObm5uUlShT7y4Fb163f663dcFg69qSAAAFZQqVIlBQYGmg+n9vb2ls1mc3BVNzfDMHT27FmdOHFCgYGBqlSpUpn7IuwAAGAHoaGhkmQGHtjHr09OLw/CDgAAdmCz2RQWFqaqVauqqKjI0eVYgpubW7lGdH5F2AEAwI4qVapklx9o2A8TlAEAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKURdgAAgKU5ddgpLi7W6NGjFRkZKS8vL0VFRWn8+PEyDMNcxzAMjRkzRmFhYfLy8lJcXJwOHDjgwKoBAIAzceqwM2nSJL377rv6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7q7AwMBS7SEhIcrMzLxin6NGjVJOTo75OnbsmL3LBgAATsLV0QX8kWPHjumFF17QmjVr5Onpabd+PTw85OHhYbf+AACA83LqkZ309HSdOHFCzZo1k6urq1xdXbV+/XrNmDFDrq6uCgkJUWFhobKzs0ttl5WVpdDQUMcUDQAAnIpTj+x06NBB3333Xam2p556SvXq1dOIESMUEREhNzc3JScnq2fPnpKkffv26ejRo4qOjnZEyQAAwMk4ddjx8/PTnXfeWarNx8dHwcHBZnu/fv2UmJiooKAg+fv76/nnn1d0dLTuueceR5QMAACcjFOHnWsxbdo0ubi4qGfPniooKFB8fLzeeecdR5cFAACchM0wDMPRRThabm6uAgIClJOTI39/f0eXA+AmVHPkl44uAb9xeGIXR5eAG+Baf7+deoIyAABAeRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApRF2AACApbk6ugAAAOzutQBHV4Dfei3HoR/v1CM7SUlJuvvuu+Xn56eqVauqe/fu2rdvX6l1zp8/r0GDBik4OFi+vr7q2bOnsrKyHFQxAABwNk4ddtavX69BgwZp27ZtWrNmjYqKinT//fcrPz/fXOfFF1/UF198oSVLlmj9+vX65Zdf1KNHDwdWDQAAnIlTn8ZauXJlqffz5s1T1apVlZ6ernbt2iknJ0f//Oc/tWjRIrVv316SNHfuXNWvX1/btm3TPffc44iyAQCAE3HqkZ3fy8m5eM4vKChIkpSenq6ioiLFxcWZ69SrV0/Vq1fX1q1br9hPQUGBcnNzS70AAIA13TRhp6SkREOHDlXr1q115513SpIyMzPl7u6uwMDAUuuGhIQoMzPzin0lJSUpICDAfEVERFRk6QAAwIFumrAzaNAg7d69W4sXLy53X6NGjVJOTo75OnbsmB0qBAAAzsip5+z8avDgwVqxYoU2bNig22+/3WwPDQ1VYWGhsrOzS43uZGVlKTQ09Ir9eXh4yMPDoyJLBgAATsKpR3YMw9DgwYO1bNkypaSkKDIystTy5s2by83NTcnJyWbbvn37dPToUUVHR9/ocgEAgBNy6pGdQYMGadGiRfrss8/k5+dnzsMJCAiQl5eXAgIC1K9fPyUmJiooKEj+/v56/vnnFR0dzZVYAABAkpOHnXfffVeSdN9995Vqnzt3rvr27StJmjZtmlxcXNSzZ08VFBQoPj5e77zzzg2uFAAAOCunDjuGYVx1HU9PT82aNUuzZs26ARUBAICbjVPP2QEAACgvwg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0wg4AALA0V0cXYHU1R37p6BLwG4cndnF0CQCAG4yRHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmEHQAAYGmuji4AuKFeC3B0Bfi913IcXQEAi2NkBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWBphBwAAWJplws6sWbNUs2ZNeXp6qlWrVvrmm28cXRIAAHAClgg7H330kRITE/XXv/5VGRkZaty4seLj43XixAlHlwYAABzMEmFn6tSp6t+/v5566ik1aNBAs2fPlre3t+bMmePo0gAAgIO5OrqA8iosLFR6erpGjRpltrm4uCguLk5bt2697DYFBQUqKCgw3+fk5EiScnNz7V5fScFZu/eJssu1GY4uAb9XAcedI3CsOxeOdSdTQcf5r7/bhvHHf983fdj573//q+Li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", "text/plain": [ "
" ] @@ -1284,13 +1311,13 @@ } ], "source": [ - "x = np.arange(1)\n", + "x = np.arange(2) # change here\n", "width = 0.40\n", - "y1 = [cHouse_read_execution_time]\n", - "y2 = [cHouse_write_execution_time]\n", + "y1 = [cHouse_read_execution_time, psql_read_execution_time] # change here\n", + "y2 = [cHouse_write_execution_time, psql_write_execution_time] # change here\n", "plt.bar(x - 0.2, y1, width)\n", "plt.bar(x + 0.2, y2, width)\n", - "plt.xticks(x, [\"Click House\"])\n", + "plt.xticks(x, [\"Click House\", \"Postgresql\"])\n", "plt.xlabel(\"Databases\")\n", "plt.ylabel(\"Seconds\")\n", "plt.legend([\"Read\", \"Write\"]) # ver\n",