├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── DateTimeDimensionGenerator.ipynb ├── LICENSE.md ├── README.md ├── app.js ├── config.js ├── dimension_table_csvs ├── date_dim.csv ├── pokemon_info.csv └── time_dim.csv ├── language_patches ├── deutsch_german.sql ├── français_french.sql └── русский_russian.sql ├── package.json ├── patches ├── 2016-07-26-dateKeyTypePatch.sql ├── 2016-07-28-dupePatch.sql ├── 2016-07-30-eraPatch.sql ├── 2016-07-30-metaPatch.sql ├── 2016-08-05-timezonePatch.sql └── pokemon_info_table_patch_2.tar ├── pokelyze_sql.sql ├── pokemon_go_db_backup.tar ├── time_dim.csv └── windowsBatch.bat /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Before submitting, check that your problem isn't solved by one of the recent patches: https://github.com/Brideau/pokelyzer#patches 2 | 3 | ### And that it has not been recently addressed in the closed issues: https://github.com/Brideau/pokelyzer/issues?q=is%3Aissue+is%3Aclosed 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.ipynb_checkpoints* 2 | node_modules/* 3 | -------------------------------------------------------------------------------- /DateTimeDimensionGenerator.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import requests\n", 12 | "import json\n", 13 | "import pandas as pd\n", 14 | "from pandas import DataFrame,Series\n", 15 | "import numpy as np\n", 16 | "import re\n", 17 | "import datetime\n", 18 | "from datetime import timedelta\n", 19 | "from dateutil import relativedelta\n", 20 | "import calendar\n", 21 | "import getpass\n", 22 | "import psycopg2\n", 23 | "from sqlalchemy import create_engine" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## Configure your PostgreSQL database info here" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 3, 36 | "metadata": { 37 | "collapsed": false 38 | }, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [ 44 | "Host Address: localhost\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "host = raw_input(\"Host Address: \")" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 37, 55 | "metadata": { 56 | "collapsed": true 57 | }, 58 | "outputs": [], 59 | "source": [ 60 | "db_name = \"pokemon_go\"\n", 61 | "username = \"pokemon_go_role\"" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 38, 67 | "metadata": { 68 | "collapsed": false 69 | }, 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "········\n" 76 | ] 77 | } 78 | ], 79 | "source": [ 80 | "password = getpass.getpass()" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "## Create the Date Table" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 5, 93 | "metadata": { 94 | "collapsed": false 95 | }, 96 | "outputs": [], 97 | "source": [ 98 | "years = xrange(2016, 2025)" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 6, 104 | "metadata": { 105 | "collapsed": false 106 | }, 107 | "outputs": [], 108 | "source": [ 109 | "start_date = str(datetime.date(years[0], 1, 1))\n", 110 | "end_date = str(datetime.date(years[-1], 12, 31))" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 7, 116 | "metadata": { 117 | "collapsed": false, 118 | "scrolled": true 119 | }, 120 | "outputs": [ 121 | { 122 | "data": { 123 | "text/plain": [ 124 | "DatetimeIndex(['2016-01-01', '2016-01-02', '2016-01-03', '2016-01-04',\n", 125 | " '2016-01-05', '2016-01-06', '2016-01-07', '2016-01-08',\n", 126 | " '2016-01-09', '2016-01-10',\n", 127 | " ...\n", 128 | " '2024-12-22', '2024-12-23', '2024-12-24', '2024-12-25',\n", 129 | " '2024-12-26', '2024-12-27', '2024-12-28', '2024-12-29',\n", 130 | " '2024-12-30', '2024-12-31'],\n", 131 | " dtype='datetime64[ns]', length=3288, freq='D')" 132 | ] 133 | }, 134 | "execution_count": 7, 135 | "metadata": {}, 136 | "output_type": "execute_result" 137 | } 138 | ], 139 | "source": [ 140 | "all_dates = pd.date_range(start_date, end_date, freq='D')\n", 141 | "all_dates" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "## All the date functions" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 8, 154 | "metadata": { 155 | "collapsed": true 156 | }, 157 | "outputs": [], 158 | "source": [ 159 | "# Given a datetime timestamp, produce a datekey\n", 160 | "def datetimeToDateKey(date):\n", 161 | " date_str = str(date)\n", 162 | " date_str = date_str.split(\" \")[0]\n", 163 | " date_str = re.sub('-', '', date_str)\n", 164 | " return date_str" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 9, 170 | "metadata": { 171 | "collapsed": true 172 | }, 173 | "outputs": [], 174 | "source": [ 175 | "# Given a datetime timestamp, convert it to a string of just the date in YYYY-mm-dd format\n", 176 | "def fullDate(date):\n", 177 | " date_str = str(date)\n", 178 | " date_str = date_str.split(\" \")[0]\n", 179 | " return date_str" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 10, 185 | "metadata": { 186 | "collapsed": true 187 | }, 188 | "outputs": [], 189 | "source": [ 190 | "# Returns the weekday as a number\n", 191 | "def weekdayNum(date):\n", 192 | " return date.isoweekday()" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 11, 198 | "metadata": { 199 | "collapsed": false 200 | }, 201 | "outputs": [], 202 | "source": [ 203 | "# Returns the weekday as a string in its full-length form\n", 204 | "def weekdayStr(date):\n", 205 | " return date.strftime(\"%A\")" 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 12, 211 | "metadata": { 212 | "collapsed": false 213 | }, 214 | "outputs": [], 215 | "source": [ 216 | "# Returns the weekday as a string in its abbreviated form\n", 217 | "def weekdayStrAbv(date):\n", 218 | " return date.strftime(\"%a\")" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": 13, 224 | "metadata": { 225 | "collapsed": false 226 | }, 227 | "outputs": [], 228 | "source": [ 229 | "# Returns the day of the month\n", 230 | "def dayNumMonth(date):\n", 231 | " return date.day" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 14, 237 | "metadata": { 238 | "collapsed": true 239 | }, 240 | "outputs": [], 241 | "source": [ 242 | "# Numbers each day, constantly increasing from the first day\n", 243 | "def dayNumOverall(date):\n", 244 | " day_one = all_dates[0]\n", 245 | " date_diff = date - day_one\n", 246 | " return date_diff.days + 1" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 15, 252 | "metadata": { 253 | "collapsed": false 254 | }, 255 | "outputs": [], 256 | "source": [ 257 | "# Returns the day of the month\n", 258 | "def isWeekday(date):\n", 259 | " if date.isoweekday() in range(1,6):\n", 260 | " return \"Weekday\"\n", 261 | " else:\n", 262 | " return \"Weekend\"" 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": 16, 268 | "metadata": { 269 | "collapsed": false 270 | }, 271 | "outputs": [], 272 | "source": [ 273 | "# Returns the day of the month\n", 274 | "def weekNum(date):\n", 275 | " return date.isocalendar()[1]" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "execution_count": 17, 281 | "metadata": { 282 | "collapsed": true 283 | }, 284 | "outputs": [], 285 | "source": [ 286 | "def weekBeginDate(date):\n", 287 | " dow = date.isoweekday()\n", 288 | " week_start = date - timedelta(days=(dow - 1))\n", 289 | " return week_start" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 18, 295 | "metadata": { 296 | "collapsed": true 297 | }, 298 | "outputs": [], 299 | "source": [ 300 | "def weekBeginDateKey(date):\n", 301 | " week_begin_date = weekBeginDate(date)\n", 302 | " date_key = datetimeToDateKey(week_begin_date)\n", 303 | " return int(date_key)" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 19, 309 | "metadata": { 310 | "collapsed": true 311 | }, 312 | "outputs": [], 313 | "source": [ 314 | "# Numbers each day, constantly increasing from the first day\n", 315 | "def weekNumOverall(date):\n", 316 | " # Find the date that the first week in the entire data set starts\n", 317 | " first_day = all_dates[0]\n", 318 | " first_week_start = weekBeginDate(first_day)\n", 319 | " \n", 320 | " # Find the date that starts the week of the current date\n", 321 | " curr_week_start = weekBeginDate(date)\n", 322 | " \n", 323 | " # Get the difference and find out how many weeks have passed\n", 324 | " date_diff = curr_week_start - first_week_start\n", 325 | " week_number = int(date_diff.days / 7.0 + 1.0)\n", 326 | " return week_number" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": 20, 332 | "metadata": { 333 | "collapsed": true 334 | }, 335 | "outputs": [], 336 | "source": [ 337 | "# Returns the weekday as a number\n", 338 | "def monthNum(date):\n", 339 | " return date.month" 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "execution_count": 21, 345 | "metadata": { 346 | "collapsed": true 347 | }, 348 | "outputs": [], 349 | "source": [ 350 | "# Returns the weekday as a number\n", 351 | "def monthNumOverall(date):\n", 352 | " start_date = all_dates[0]\n", 353 | " rel_date = relativedelta.relativedelta(date, start_date)\n", 354 | " month_diff = rel_date.years * 12 + rel_date.months\n", 355 | " return month_diff + 1" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 22, 361 | "metadata": { 362 | "collapsed": false 363 | }, 364 | "outputs": [], 365 | "source": [ 366 | "# Returns the month as a string in its full-length form\n", 367 | "def monthStr(date):\n", 368 | " return date.strftime(\"%B\")" 369 | ] 370 | }, 371 | { 372 | "cell_type": "code", 373 | "execution_count": 23, 374 | "metadata": { 375 | "collapsed": false 376 | }, 377 | "outputs": [], 378 | "source": [ 379 | "# Returns the month as a string in its abbreviated form\n", 380 | "def monthStrAbv(date):\n", 381 | " return date.strftime(\"%b\")" 382 | ] 383 | }, 384 | { 385 | "cell_type": "code", 386 | "execution_count": 24, 387 | "metadata": { 388 | "collapsed": false 389 | }, 390 | "outputs": [], 391 | "source": [ 392 | "# Returns the quarter in the year\n", 393 | "def quarter(date):\n", 394 | " month = date.month\n", 395 | " quarter = month / 4 + 1\n", 396 | " return quarter" 397 | ] 398 | }, 399 | { 400 | "cell_type": "code", 401 | "execution_count": 25, 402 | "metadata": { 403 | "collapsed": false 404 | }, 405 | "outputs": [], 406 | "source": [ 407 | "# Returns the year as a string\n", 408 | "def year(date):\n", 409 | " return date.strftime(\"%Y\")" 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "execution_count": 26, 415 | "metadata": { 416 | "collapsed": false 417 | }, 418 | "outputs": [], 419 | "source": [ 420 | "# Returns the year and month as a concatenated string\n", 421 | "def yearmo(date):\n", 422 | " year = date.strftime(\"%Y\")\n", 423 | " month = date.strftime(\"%m\")\n", 424 | " return year + month" 425 | ] 426 | }, 427 | { 428 | "cell_type": "code", 429 | "execution_count": 27, 430 | "metadata": { 431 | "collapsed": true 432 | }, 433 | "outputs": [], 434 | "source": [ 435 | "# Returns whether or not the date is the last day of the month\n", 436 | "def isMonthEnd(date):\n", 437 | " year = date.year\n", 438 | " month = date.month\n", 439 | " \n", 440 | " month_end = calendar.monthrange(year, month)[1]\n", 441 | " \n", 442 | " if (month_end == date.day):\n", 443 | " return \"Month End\"\n", 444 | " else:\n", 445 | " return \"Not Month End\"" 446 | ] 447 | }, 448 | { 449 | "cell_type": "code", 450 | "execution_count": 28, 451 | "metadata": { 452 | "collapsed": false 453 | }, 454 | "outputs": [], 455 | "source": [ 456 | "# Use the date functions to make a dateframe\n", 457 | "\n", 458 | "# Dates\n", 459 | "date_dim = DataFrame(all_dates, columns=[\"full_date\"])\n", 460 | "date_dim[\"date_key\"] = date_dim[\"full_date\"].map(datetimeToDateKey)\n", 461 | "date_dim = date_dim[['date_key', 'full_date']] # Reorder\n", 462 | "\n", 463 | "# Days of Week\n", 464 | "date_dim[\"day_of_week\"] = date_dim[\"full_date\"].map(weekdayNum)\n", 465 | "date_dim[\"day_of_week_name\"] = date_dim[\"full_date\"].map(weekdayStr)\n", 466 | "date_dim[\"day_of_week_name_abbrev\"] = date_dim[\"full_date\"].map(weekdayStrAbv)\n", 467 | "\n", 468 | "date_dim[\"day_of_month\"] = date_dim[\"full_date\"].map(dayNumMonth)\n", 469 | "date_dim[\"day_number_overall\"] = date_dim[\"full_date\"].map(dayNumOverall)\n", 470 | "date_dim[\"day_number_overall\"] = date_dim[\"full_date\"].map(dayNumOverall)\n", 471 | "\n", 472 | "date_dim[\"weekday_flag\"] = date_dim[\"full_date\"].map(isWeekday)\n", 473 | "date_dim[\"week_number\"] = date_dim[\"full_date\"].map(weekNum)\n", 474 | "date_dim[\"week_number_overall\"] = date_dim[\"full_date\"].map(weekNumOverall)\n", 475 | "\n", 476 | "date_dim[\"week_begin_date\"] = date_dim[\"full_date\"].map(weekBeginDate)\n", 477 | "date_dim[\"week_begin_date_key\"] = date_dim[\"full_date\"].map(weekBeginDateKey)\n", 478 | "\n", 479 | "date_dim[\"month_number\"] = date_dim[\"full_date\"].map(monthNum)\n", 480 | "date_dim[\"month_number_overall\"] = date_dim[\"full_date\"].map(monthNumOverall)\n", 481 | "date_dim[\"month\"] = date_dim[\"full_date\"].map(monthStr)\n", 482 | "date_dim[\"month_abbrev\"] = date_dim[\"full_date\"].map(monthStrAbv)\n", 483 | "\n", 484 | "date_dim[\"quarter\"] = date_dim[\"full_date\"].map(quarter)\n", 485 | "\n", 486 | "date_dim[\"year\"] = date_dim[\"full_date\"].map(year)\n", 487 | "date_dim[\"year_month\"] = date_dim[\"full_date\"].map(yearmo)\n", 488 | "\n", 489 | "date_dim[\"month_end_flag\"] = date_dim[\"full_date\"].map(isMonthEnd)" 490 | ] 491 | }, 492 | { 493 | "cell_type": "markdown", 494 | "metadata": { 495 | "collapsed": true 496 | }, 497 | "source": [ 498 | "## Create the Time Table" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": 6, 504 | "metadata": { 505 | "collapsed": true 506 | }, 507 | "outputs": [], 508 | "source": [ 509 | "from datetime import time\n", 510 | "import math" 511 | ] 512 | }, 513 | { 514 | "cell_type": "code", 515 | "execution_count": 7, 516 | "metadata": { 517 | "collapsed": true 518 | }, 519 | "outputs": [], 520 | "source": [ 521 | "# 1440 minutes in a day\n", 522 | "minutes = xrange(0,1440)" 523 | ] 524 | }, 525 | { 526 | "cell_type": "code", 527 | "execution_count": 56, 528 | "metadata": { 529 | "collapsed": true 530 | }, 531 | "outputs": [], 532 | "source": [ 533 | "# Given a minute number, return the 12-hour time label\n", 534 | "def time_label_12(min_num):\n", 535 | " hours, minutes = divmod(int(min_num), 60)\n", 536 | " timestamp = time(hour=hours, minute=minutes)\n", 537 | " return str(time.strftime(timestamp, '%I:%M %p'))" 538 | ] 539 | }, 540 | { 541 | "cell_type": "code", 542 | "execution_count": 57, 543 | "metadata": { 544 | "collapsed": true 545 | }, 546 | "outputs": [], 547 | "source": [ 548 | "# Given a minute number, return the 24-hour time label\n", 549 | "def time_label_24(min_num):\n", 550 | " hours, minutes = divmod(int(min_num), 60)\n", 551 | " timestamp = time(hour=hours, minute=minutes)\n", 552 | " return str(time.strftime(timestamp, '%H:%M'))" 553 | ] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": 58, 558 | "metadata": { 559 | "collapsed": true 560 | }, 561 | "outputs": [], 562 | "source": [ 563 | "# Given a minute number, return the 15 minute interval it occures in\n", 564 | "def time_interval_15_min(min_num):\n", 565 | " return str(int(math.floor(min_num / 15.0)))" 566 | ] 567 | }, 568 | { 569 | "cell_type": "code", 570 | "execution_count": 59, 571 | "metadata": { 572 | "collapsed": true 573 | }, 574 | "outputs": [], 575 | "source": [ 576 | "# Given a minute number, return the 30 minute interval it occures in\n", 577 | "def time_interval_30_min(min_num):\n", 578 | " return str(int(math.floor(min_num / 30.0)))" 579 | ] 580 | }, 581 | { 582 | "cell_type": "code", 583 | "execution_count": 60, 584 | "metadata": { 585 | "collapsed": true 586 | }, 587 | "outputs": [], 588 | "source": [ 589 | "# Given a minute number, return the 60 minute interval it occures in\n", 590 | "def time_interval_60_min(min_num):\n", 591 | " return str(int(math.floor(min_num / 60.0)))" 592 | ] 593 | }, 594 | { 595 | "cell_type": "code", 596 | "execution_count": 61, 597 | "metadata": { 598 | "collapsed": true 599 | }, 600 | "outputs": [], 601 | "source": [ 602 | "# Given a minute number, return the 12-hour time label \n", 603 | "# with only hours (this takes up less space and is useful in some cases)\n", 604 | "def label_hh(min_num):\n", 605 | " hours, minutes = divmod(int(min_num), 60)\n", 606 | " timestamp = time(hour=hours, minute=minutes)\n", 607 | " return str(time.strftime(timestamp, '%I %p'))" 608 | ] 609 | }, 610 | { 611 | "cell_type": "code", 612 | "execution_count": 62, 613 | "metadata": { 614 | "collapsed": true 615 | }, 616 | "outputs": [], 617 | "source": [ 618 | "# Given a minute number, return the 24-hour time label with just hours\n", 619 | "def label_hh24(min_num):\n", 620 | " hours, minutes = divmod(int(min_num), 60)\n", 621 | " timestamp = time(hour=hours, minute=minutes)\n", 622 | " return str(time.strftime(timestamp, '%H'))" 623 | ] 624 | }, 625 | { 626 | "cell_type": "code", 627 | "execution_count": 63, 628 | "metadata": { 629 | "collapsed": true 630 | }, 631 | "outputs": [], 632 | "source": [ 633 | "# Given a minute number, return the 15 minute interval label for a 24-hour clock\n", 634 | "def label_15_min_24(min_num):\n", 635 | " interval_num = time_interval_15_min(min_num)\n", 636 | " int_min_num = int(interval_num) * 15\n", 637 | " hours, minutes = divmod(int_min_num, 60)\n", 638 | " timestamp = time(hour=hours, minute=minutes)\n", 639 | " return str(time.strftime(timestamp, '%H:%M'))" 640 | ] 641 | }, 642 | { 643 | "cell_type": "code", 644 | "execution_count": 64, 645 | "metadata": { 646 | "collapsed": true 647 | }, 648 | "outputs": [], 649 | "source": [ 650 | "# Given a minute number, return the 30 minute interval label for a 24-hour clock\n", 651 | "def label_30_min_24(min_num):\n", 652 | " interval_num = time_interval_30_min(min_num)\n", 653 | " int_min_num = int(interval_num) * 30\n", 654 | " hours, minutes = divmod(int_min_num, 60)\n", 655 | " timestamp = time(hour=hours, minute=minutes)\n", 656 | " return str(time.strftime(timestamp, '%H:%M'))" 657 | ] 658 | }, 659 | { 660 | "cell_type": "code", 661 | "execution_count": 65, 662 | "metadata": { 663 | "collapsed": true 664 | }, 665 | "outputs": [], 666 | "source": [ 667 | "# Given a minute number, return the 60 minute interval label for a 24-hour clock\n", 668 | "def label_60_min_24(min_num):\n", 669 | " interval_num = time_interval_60_min(min_num)\n", 670 | " int_min_num = int(interval_num) * 60\n", 671 | " hours, minutes = divmod(int_min_num, 60)\n", 672 | " timestamp = time(hour=hours, minute=minutes)\n", 673 | " return str(time.strftime(timestamp, '%H:%M'))" 674 | ] 675 | }, 676 | { 677 | "cell_type": "code", 678 | "execution_count": 66, 679 | "metadata": { 680 | "collapsed": true 681 | }, 682 | "outputs": [], 683 | "source": [ 684 | "# Given a minute number, return the 15 minute interval label for a 12-hour clock\n", 685 | "def label_15_min_12(min_num):\n", 686 | " interval_num = time_interval_15_min(min_num)\n", 687 | " int_min_num = int(interval_num) * 15\n", 688 | " hours, minutes = divmod(int_min_num, 60)\n", 689 | " timestamp = time(hour=hours, minute=minutes)\n", 690 | " return str(time.strftime(timestamp, '%I:%M %p'))" 691 | ] 692 | }, 693 | { 694 | "cell_type": "code", 695 | "execution_count": 67, 696 | "metadata": { 697 | "collapsed": true 698 | }, 699 | "outputs": [], 700 | "source": [ 701 | "# Given a minute number, return the 30 minute interval label for a 12-hour clock\n", 702 | "def label_30_min_12(min_num):\n", 703 | " interval_num = time_interval_30_min(min_num)\n", 704 | " int_min_num = int(interval_num) * 30\n", 705 | " hours, minutes = divmod(int_min_num, 60)\n", 706 | " timestamp = time(hour=hours, minute=minutes)\n", 707 | " return str(time.strftime(timestamp, '%I:%M %p'))" 708 | ] 709 | }, 710 | { 711 | "cell_type": "code", 712 | "execution_count": 68, 713 | "metadata": { 714 | "collapsed": true 715 | }, 716 | "outputs": [], 717 | "source": [ 718 | "# Given a miute number, return the 60 minute interval label for a 12-hour clock\n", 719 | "def label_60_min_12(min_num):\n", 720 | " interval_num = time_interval_60_min(min_num)\n", 721 | " int_min_num = int(interval_num) * 60\n", 722 | " hours, minutes = divmod(int_min_num, 60)\n", 723 | " timestamp = time(hour=hours, minute=minutes)\n", 724 | " return str(time.strftime(timestamp, '%I:%M %p'))" 725 | ] 726 | }, 727 | { 728 | "cell_type": "code", 729 | "execution_count": 69, 730 | "metadata": { 731 | "collapsed": true 732 | }, 733 | "outputs": [], 734 | "source": [ 735 | "# Given a minute, return just the minute portion\n", 736 | "def minute_after_hour(min_num):\n", 737 | " hours, minutes = divmod(int(min_num), 60)\n", 738 | " timestamp = time(hour=hours, minute=minutes)\n", 739 | " return str(int(time.strftime(timestamp, '%M')))" 740 | ] 741 | }, 742 | { 743 | "cell_type": "code", 744 | "execution_count": 30, 745 | "metadata": { 746 | "collapsed": false 747 | }, 748 | "outputs": [ 749 | { 750 | "data": { 751 | "text/plain": [ 752 | "'1'" 753 | ] 754 | }, 755 | "execution_count": 30, 756 | "metadata": {}, 757 | "output_type": "execute_result" 758 | } 759 | ], 760 | "source": [ 761 | "minute_after_hour(61)" 762 | ] 763 | }, 764 | { 765 | "cell_type": "code", 766 | "execution_count": 70, 767 | "metadata": { 768 | "collapsed": false, 769 | "scrolled": true 770 | }, 771 | "outputs": [], 772 | "source": [ 773 | "time_dim = DataFrame(Series(minutes), columns=[\"time_key\"])\n", 774 | "time_dim[\"time_label_24\"] = time_dim[\"time_key\"].map(time_label_24)\n", 775 | "time_dim[\"time_label_12\"] = time_dim[\"time_key\"].map(time_label_12)\n", 776 | "\n", 777 | "time_dim[\"time_interval_15min\"] = time_dim[\"time_key\"].map(time_interval_15_min)\n", 778 | "time_dim[\"time_interval_30min\"] = time_dim[\"time_key\"].map(time_interval_30_min)\n", 779 | "time_dim[\"time_interval_60min\"] = time_dim[\"time_key\"].map(time_interval_60_min)\n", 780 | "\n", 781 | "time_dim[\"label_hh\"] = time_dim[\"time_key\"].map(label_hh)\n", 782 | "time_dim[\"label_hh24\"] = time_dim[\"time_key\"].map(label_hh24)\n", 783 | "\n", 784 | "time_dim[\"label_15min_24\"] = time_dim[\"time_key\"].map(label_15_min_24)\n", 785 | "time_dim[\"label_30min_24\"] = time_dim[\"time_key\"].map(label_30_min_24)\n", 786 | "time_dim[\"label_60min_24\"] = time_dim[\"time_key\"].map(label_60_min_24)\n", 787 | "\n", 788 | "time_dim[\"label_15min_12\"] = time_dim[\"time_key\"].map(label_15_min_12)\n", 789 | "time_dim[\"label_30min_12\"] = time_dim[\"time_key\"].map(label_30_min_12)\n", 790 | "time_dim[\"label_60min_12\"] = time_dim[\"time_key\"].map(label_60_min_12)\n", 791 | "\n", 792 | "time_dim[\"minute_after_hour\"] = time_dim[\"time_key\"].map(minute_after_hour)" 793 | ] 794 | }, 795 | { 796 | "cell_type": "markdown", 797 | "metadata": {}, 798 | "source": [ 799 | "## Write the data to the database" 800 | ] 801 | }, 802 | { 803 | "cell_type": "code", 804 | "execution_count": 71, 805 | "metadata": { 806 | "collapsed": false 807 | }, 808 | "outputs": [ 809 | { 810 | "ename": "NameError", 811 | "evalue": "name 'date_dim' is not defined", 812 | "output_type": "error", 813 | "traceback": [ 814 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 815 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 816 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdate_dim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhead\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 817 | "\u001b[0;31mNameError\u001b[0m: name 'date_dim' is not defined" 818 | ] 819 | } 820 | ], 821 | "source": [ 822 | "date_dim.head()" 823 | ] 824 | }, 825 | { 826 | "cell_type": "code", 827 | "execution_count": 32, 828 | "metadata": { 829 | "collapsed": false, 830 | "scrolled": true 831 | }, 832 | "outputs": [ 833 | { 834 | "data": { 835 | "text/html": [ 836 | "
\n", 837 | "\n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | " \n", 846 | " \n", 847 | " \n", 848 | " \n", 849 | " \n", 850 | " \n", 851 | " \n", 852 | " \n", 853 | " \n", 854 | " \n", 855 | " \n", 856 | " \n", 857 | " \n", 858 | " \n", 859 | " \n", 860 | " \n", 861 | " \n", 862 | " \n", 863 | " \n", 864 | " \n", 865 | " \n", 866 | " \n", 867 | " \n", 868 | " \n", 869 | " \n", 870 | " \n", 871 | " \n", 872 | " \n", 873 | " \n", 874 | " \n", 875 | " \n", 876 | " \n", 877 | " \n", 878 | " \n", 879 | " \n", 880 | " \n", 881 | " \n", 882 | " \n", 883 | " \n", 884 | " \n", 885 | " \n", 886 | " \n", 887 | " \n", 888 | " \n", 889 | " \n", 890 | " \n", 891 | " \n", 892 | " \n", 893 | " \n", 894 | " \n", 895 | " \n", 896 | " \n", 897 | " \n", 898 | " \n", 899 | " \n", 900 | " \n", 901 | " \n", 902 | " \n", 903 | " \n", 904 | " \n", 905 | " \n", 906 | " \n", 907 | " \n", 908 | " \n", 909 | " \n", 910 | " \n", 911 | " \n", 912 | " \n", 913 | " \n", 914 | " \n", 915 | " \n", 916 | " \n", 917 | " \n", 918 | " \n", 919 | " \n", 920 | " \n", 921 | " \n", 922 | " \n", 923 | " \n", 924 | " \n", 925 | " \n", 926 | " \n", 927 | " \n", 928 | " \n", 929 | " \n", 930 | " \n", 931 | " \n", 932 | " \n", 933 | " \n", 934 | " \n", 935 | " \n", 936 | " \n", 937 | " \n", 938 | " \n", 939 | " \n", 940 | " \n", 941 | " \n", 942 | " \n", 943 | " \n", 944 | " \n", 945 | " \n", 946 | " \n", 947 | " \n", 948 | " \n", 949 | " \n", 950 | " \n", 951 | " \n", 952 | " \n", 953 | " \n", 954 | " \n", 955 | " \n", 956 | " \n", 957 | " \n", 958 | " \n", 959 | " \n", 960 | " \n", 961 | " \n", 962 | " \n", 963 | " \n", 964 | " \n", 965 | " \n", 966 | " \n", 967 | " \n", 968 | " \n", 969 | " \n", 970 | " \n", 971 | " \n", 972 | " \n", 973 | " \n", 974 | " \n", 975 | " \n", 976 | " \n", 977 | " \n", 978 | " \n", 979 | " \n", 980 | " \n", 981 | " \n", 982 | " \n", 983 | " \n", 984 | " \n", 985 | " \n", 986 | " \n", 987 | " \n", 988 | " \n", 989 | " \n", 990 | " \n", 991 | " \n", 992 | " \n", 993 | " \n", 994 | " \n", 995 | " \n", 996 | " \n", 997 | " \n", 998 | " \n", 999 | " \n", 1000 | " \n", 1001 | " \n", 1002 | " \n", 1003 | " \n", 1004 | " \n", 1005 | " \n", 1006 | " \n", 1007 | " \n", 1008 | " \n", 1009 | " \n", 1010 | " \n", 1011 | " \n", 1012 | " \n", 1013 | " \n", 1014 | " \n", 1015 | " \n", 1016 | " \n", 1017 | " \n", 1018 | " \n", 1019 | " \n", 1020 | " \n", 1021 | " \n", 1022 | " \n", 1023 | " \n", 1024 | " \n", 1025 | " \n", 1026 | " \n", 1027 | " \n", 1028 | " \n", 1029 | " \n", 1030 | " \n", 1031 | " \n", 1032 | " \n", 1033 | " \n", 1034 | " \n", 1035 | " \n", 1036 | " \n", 1037 | " \n", 1038 | " \n", 1039 | " \n", 1040 | " \n", 1041 | " \n", 1042 | " \n", 1043 | " \n", 1044 | " \n", 1045 | " \n", 1046 | " \n", 1047 | " \n", 1048 | " \n", 1049 | " \n", 1050 | " \n", 1051 | " \n", 1052 | " \n", 1053 | " \n", 1054 | " \n", 1055 | " \n", 1056 | " \n", 1057 | " \n", 1058 | " \n", 1059 | " \n", 1060 | " \n", 1061 | " \n", 1062 | " \n", 1063 | " \n", 1064 | " \n", 1065 | " \n", 1066 | " \n", 1067 | " \n", 1068 | " \n", 1069 | " \n", 1070 | " \n", 1071 | " \n", 1072 | " \n", 1073 | " \n", 1074 | " \n", 1075 | " \n", 1076 | " \n", 1077 | " \n", 1078 | " \n", 1079 | " \n", 1080 | " \n", 1081 | " \n", 1082 | " \n", 1083 | " \n", 1084 | " \n", 1085 | " \n", 1086 | " \n", 1087 | " \n", 1088 | " \n", 1089 | " \n", 1090 | " \n", 1091 | " \n", 1092 | " \n", 1093 | " \n", 1094 | " \n", 1095 | " \n", 1096 | " \n", 1097 | " \n", 1098 | " \n", 1099 | " \n", 1100 | " \n", 1101 | " \n", 1102 | " \n", 1103 | " \n", 1104 | " \n", 1105 | " \n", 1106 | " \n", 1107 | " \n", 1108 | " \n", 1109 | " \n", 1110 | " \n", 1111 | " \n", 1112 | " \n", 1113 | " \n", 1114 | " \n", 1115 | " \n", 1116 | " \n", 1117 | " \n", 1118 | " \n", 1119 | " \n", 1120 | " \n", 1121 | " \n", 1122 | " \n", 1123 | " \n", 1124 | " \n", 1125 | " \n", 1126 | " \n", 1127 | " \n", 1128 | " \n", 1129 | " \n", 1130 | " \n", 1131 | " \n", 1132 | " \n", 1133 | " \n", 1134 | " \n", 1135 | " \n", 1136 | " \n", 1137 | " \n", 1138 | " \n", 1139 | " \n", 1140 | " \n", 1141 | " \n", 1142 | " \n", 1143 | " \n", 1144 | " \n", 1145 | " \n", 1146 | " \n", 1147 | " \n", 1148 | " \n", 1149 | " \n", 1150 | " \n", 1151 | " \n", 1152 | " \n", 1153 | " \n", 1154 | " \n", 1155 | " \n", 1156 | " \n", 1157 | " \n", 1158 | " \n", 1159 | " \n", 1160 | " \n", 1161 | " \n", 1162 | " \n", 1163 | " \n", 1164 | " \n", 1165 | " \n", 1166 | " \n", 1167 | " \n", 1168 | " \n", 1169 | " \n", 1170 | " \n", 1171 | " \n", 1172 | " \n", 1173 | " \n", 1174 | " \n", 1175 | " \n", 1176 | " \n", 1177 | " \n", 1178 | " \n", 1179 | " \n", 1180 | " \n", 1181 | " \n", 1182 | " \n", 1183 | " \n", 1184 | " \n", 1185 | " \n", 1186 | " \n", 1187 | " \n", 1188 | " \n", 1189 | " \n", 1190 | " \n", 1191 | " \n", 1192 | " \n", 1193 | " \n", 1194 | " \n", 1195 | " \n", 1196 | " \n", 1197 | " \n", 1198 | " \n", 1199 | " \n", 1200 | " \n", 1201 | " \n", 1202 | " \n", 1203 | " \n", 1204 | " \n", 1205 | " \n", 1206 | " \n", 1207 | " \n", 1208 | " \n", 1209 | " \n", 1210 | " \n", 1211 | " \n", 1212 | " \n", 1213 | " \n", 1214 | " \n", 1215 | " \n", 1216 | " \n", 1217 | " \n", 1218 | " \n", 1219 | " \n", 1220 | " \n", 1221 | " \n", 1222 | " \n", 1223 | " \n", 1224 | " \n", 1225 | " \n", 1226 | " \n", 1227 | " \n", 1228 | " \n", 1229 | " \n", 1230 | " \n", 1231 | " \n", 1232 | " \n", 1233 | " \n", 1234 | " \n", 1235 | " \n", 1236 | " \n", 1237 | " \n", 1238 | " \n", 1239 | " \n", 1240 | " \n", 1241 | " \n", 1242 | " \n", 1243 | " \n", 1244 | " \n", 1245 | " \n", 1246 | " \n", 1247 | " \n", 1248 | " \n", 1249 | " \n", 1250 | " \n", 1251 | " \n", 1252 | " \n", 1253 | " \n", 1254 | " \n", 1255 | " \n", 1256 | " \n", 1257 | " \n", 1258 | " \n", 1259 | " \n", 1260 | " \n", 1261 | " \n", 1262 | " \n", 1263 | " \n", 1264 | " \n", 1265 | " \n", 1266 | " \n", 1267 | " \n", 1268 | " \n", 1269 | " \n", 1270 | " \n", 1271 | " \n", 1272 | " \n", 1273 | " \n", 1274 | " \n", 1275 | " \n", 1276 | " \n", 1277 | " \n", 1278 | " \n", 1279 | " \n", 1280 | " \n", 1281 | " \n", 1282 | " \n", 1283 | " \n", 1284 | " \n", 1285 | " \n", 1286 | " \n", 1287 | " \n", 1288 | " \n", 1289 | " \n", 1290 | " \n", 1291 | " \n", 1292 | " \n", 1293 | " \n", 1294 | " \n", 1295 | " \n", 1296 | " \n", 1297 | " \n", 1298 | " \n", 1299 | " \n", 1300 | " \n", 1301 | " \n", 1302 | " \n", 1303 | " \n", 1304 | " \n", 1305 | " \n", 1306 | " \n", 1307 | " \n", 1308 | " \n", 1309 | " \n", 1310 | " \n", 1311 | " \n", 1312 | " \n", 1313 | " \n", 1314 | " \n", 1315 | " \n", 1316 | " \n", 1317 | " \n", 1318 | " \n", 1319 | " \n", 1320 | " \n", 1321 | " \n", 1322 | " \n", 1323 | " \n", 1324 | " \n", 1325 | " \n", 1326 | " \n", 1327 | " \n", 1328 | " \n", 1329 | " \n", 1330 | " \n", 1331 | " \n", 1332 | " \n", 1333 | " \n", 1334 | " \n", 1335 | " \n", 1336 | " \n", 1337 | " \n", 1338 | " \n", 1339 | " \n", 1340 | " \n", 1341 | " \n", 1342 | " \n", 1343 | " \n", 1344 | " \n", 1345 | " \n", 1346 | " \n", 1347 | " \n", 1348 | " \n", 1349 | " \n", 1350 | " \n", 1351 | " \n", 1352 | " \n", 1353 | " \n", 1354 | " \n", 1355 | " \n", 1356 | " \n", 1357 | " \n", 1358 | " \n", 1359 | " \n", 1360 | " \n", 1361 | " \n", 1362 | " \n", 1363 | " \n", 1364 | " \n", 1365 | " \n", 1366 | " \n", 1367 | " \n", 1368 | " \n", 1369 | " \n", 1370 | " \n", 1371 | " \n", 1372 | " \n", 1373 | " \n", 1374 | " \n", 1375 | " \n", 1376 | " \n", 1377 | " \n", 1378 | " \n", 1379 | " \n", 1380 | " \n", 1381 | " \n", 1382 | " \n", 1383 | " \n", 1384 | " \n", 1385 | " \n", 1386 | " \n", 1387 | " \n", 1388 | " \n", 1389 | " \n", 1390 | " \n", 1391 | " \n", 1392 | " \n", 1393 | " \n", 1394 | " \n", 1395 | " \n", 1396 | " \n", 1397 | " \n", 1398 | " \n", 1399 | " \n", 1400 | " \n", 1401 | " \n", 1402 | " \n", 1403 | " \n", 1404 | " \n", 1405 | " \n", 1406 | " \n", 1407 | " \n", 1408 | " \n", 1409 | " \n", 1410 | " \n", 1411 | " \n", 1412 | " \n", 1413 | " \n", 1414 | " \n", 1415 | " \n", 1416 | " \n", 1417 | " \n", 1418 | " \n", 1419 | " \n", 1420 | " \n", 1421 | " \n", 1422 | " \n", 1423 | " \n", 1424 | " \n", 1425 | " \n", 1426 | " \n", 1427 | " \n", 1428 | " \n", 1429 | " \n", 1430 | " \n", 1431 | " \n", 1432 | " \n", 1433 | " \n", 1434 | " \n", 1435 | " \n", 1436 | " \n", 1437 | " \n", 1438 | " \n", 1439 | " \n", 1440 | " \n", 1441 | " \n", 1442 | " \n", 1443 | " \n", 1444 | " \n", 1445 | " \n", 1446 | " \n", 1447 | " \n", 1448 | " \n", 1449 | " \n", 1450 | " \n", 1451 | " \n", 1452 | " \n", 1453 | " \n", 1454 | " \n", 1455 | " \n", 1456 | " \n", 1457 | " \n", 1458 | " \n", 1459 | " \n", 1460 | " \n", 1461 | " \n", 1462 | " \n", 1463 | " \n", 1464 | " \n", 1465 | " \n", 1466 | " \n", 1467 | " \n", 1468 | " \n", 1469 | " \n", 1470 | " \n", 1471 | " \n", 1472 | " \n", 1473 | " \n", 1474 | " \n", 1475 | " \n", 1476 | " \n", 1477 | " \n", 1478 | " \n", 1479 | " \n", 1480 | " \n", 1481 | " \n", 1482 | " \n", 1483 | " \n", 1484 | " \n", 1485 | " \n", 1486 | " \n", 1487 | " \n", 1488 | " \n", 1489 | " \n", 1490 | " \n", 1491 | " \n", 1492 | " \n", 1493 | " \n", 1494 | " \n", 1495 | " \n", 1496 | " \n", 1497 | " \n", 1498 | " \n", 1499 | " \n", 1500 | " \n", 1501 | " \n", 1502 | " \n", 1503 | " \n", 1504 | " \n", 1505 | " \n", 1506 | " \n", 1507 | " \n", 1508 | " \n", 1509 | " \n", 1510 | " \n", 1511 | " \n", 1512 | " \n", 1513 | " \n", 1514 | " \n", 1515 | " \n", 1516 | " \n", 1517 | " \n", 1518 | " \n", 1519 | " \n", 1520 | " \n", 1521 | " \n", 1522 | " \n", 1523 | " \n", 1524 | " \n", 1525 | " \n", 1526 | " \n", 1527 | " \n", 1528 | " \n", 1529 | " \n", 1530 | " \n", 1531 | " \n", 1532 | " \n", 1533 | " \n", 1534 | " \n", 1535 | " \n", 1536 | " \n", 1537 | " \n", 1538 | " \n", 1539 | " \n", 1540 | " \n", 1541 | " \n", 1542 | " \n", 1543 | " \n", 1544 | " \n", 1545 | " \n", 1546 | " \n", 1547 | " \n", 1548 | " \n", 1549 | " \n", 1550 | " \n", 1551 | " \n", 1552 | " \n", 1553 | " \n", 1554 | " \n", 1555 | " \n", 1556 | " \n", 1557 | " \n", 1558 | " \n", 1559 | " \n", 1560 | " \n", 1561 | " \n", 1562 | " \n", 1563 | " \n", 1564 | " \n", 1565 | " \n", 1566 | " \n", 1567 | " \n", 1568 | " \n", 1569 | " \n", 1570 | " \n", 1571 | " \n", 1572 | " \n", 1573 | " \n", 1574 | " \n", 1575 | " \n", 1576 | " \n", 1577 | " \n", 1578 | " \n", 1579 | " \n", 1580 | " \n", 1581 | " \n", 1582 | " \n", 1583 | " \n", 1584 | " \n", 1585 | " \n", 1586 | " \n", 1587 | " \n", 1588 | " \n", 1589 | " \n", 1590 | " \n", 1591 | " \n", 1592 | " \n", 1593 | " \n", 1594 | " \n", 1595 | " \n", 1596 | " \n", 1597 | " \n", 1598 | " \n", 1599 | " \n", 1600 | " \n", 1601 | " \n", 1602 | " \n", 1603 | " \n", 1604 | " \n", 1605 | " \n", 1606 | " \n", 1607 | " \n", 1608 | " \n", 1609 | " \n", 1610 | " \n", 1611 | " \n", 1612 | " \n", 1613 | " \n", 1614 | " \n", 1615 | " \n", 1616 | " \n", 1617 | " \n", 1618 | " \n", 1619 | " \n", 1620 | " \n", 1621 | " \n", 1622 | " \n", 1623 | " \n", 1624 | " \n", 1625 | " \n", 1626 | " \n", 1627 | " \n", 1628 | " \n", 1629 | " \n", 1630 | " \n", 1631 | " \n", 1632 | " \n", 1633 | " \n", 1634 | " \n", 1635 | " \n", 1636 | " \n", 1637 | " \n", 1638 | " \n", 1639 | " \n", 1640 | " \n", 1641 | " \n", 1642 | " \n", 1643 | " \n", 1644 | " \n", 1645 | " \n", 1646 | " \n", 1647 | " \n", 1648 | " \n", 1649 | " \n", 1650 | " \n", 1651 | " \n", 1652 | " \n", 1653 | " \n", 1654 | " \n", 1655 | " \n", 1656 | " \n", 1657 | " \n", 1658 | " \n", 1659 | " \n", 1660 | " \n", 1661 | " \n", 1662 | " \n", 1663 | " \n", 1664 | " \n", 1665 | " \n", 1666 | " \n", 1667 | " \n", 1668 | " \n", 1669 | " \n", 1670 | " \n", 1671 | " \n", 1672 | " \n", 1673 | " \n", 1674 | " \n", 1675 | " \n", 1676 | " \n", 1677 | " \n", 1678 | " \n", 1679 | " \n", 1680 | " \n", 1681 | " \n", 1682 | " \n", 1683 | " \n", 1684 | " \n", 1685 | " \n", 1686 | " \n", 1687 | " \n", 1688 | " \n", 1689 | " \n", 1690 | " \n", 1691 | " \n", 1692 | " \n", 1693 | " \n", 1694 | " \n", 1695 | " \n", 1696 | " \n", 1697 | " \n", 1698 | " \n", 1699 | " \n", 1700 | " \n", 1701 | " \n", 1702 | " \n", 1703 | " \n", 1704 | " \n", 1705 | " \n", 1706 | " \n", 1707 | " \n", 1708 | " \n", 1709 | " \n", 1710 | " \n", 1711 | " \n", 1712 | " \n", 1713 | " \n", 1714 | " \n", 1715 | " \n", 1716 | " \n", 1717 | " \n", 1718 | " \n", 1719 | " \n", 1720 | " \n", 1721 | " \n", 1722 | " \n", 1723 | " \n", 1724 | " \n", 1725 | " \n", 1726 | " \n", 1727 | " \n", 1728 | " \n", 1729 | " \n", 1730 | " \n", 1731 | " \n", 1732 | " \n", 1733 | " \n", 1734 | " \n", 1735 | " \n", 1736 | " \n", 1737 | " \n", 1738 | " \n", 1739 | " \n", 1740 | " \n", 1741 | " \n", 1742 | " \n", 1743 | " \n", 1744 | " \n", 1745 | " \n", 1746 | " \n", 1747 | " \n", 1748 | " \n", 1749 | " \n", 1750 | " \n", 1751 | " \n", 1752 | " \n", 1753 | " \n", 1754 | " \n", 1755 | " \n", 1756 | " \n", 1757 | " \n", 1758 | " \n", 1759 | " \n", 1760 | " \n", 1761 | " \n", 1762 | " \n", 1763 | " \n", 1764 | " \n", 1765 | " \n", 1766 | " \n", 1767 | " \n", 1768 | " \n", 1769 | " \n", 1770 | " \n", 1771 | " \n", 1772 | " \n", 1773 | " \n", 1774 | " \n", 1775 | " \n", 1776 | " \n", 1777 | " \n", 1778 | " \n", 1779 | " \n", 1780 | " \n", 1781 | " \n", 1782 | " \n", 1783 | " \n", 1784 | " \n", 1785 | " \n", 1786 | " \n", 1787 | " \n", 1788 | " \n", 1789 | " \n", 1790 | " \n", 1791 | " \n", 1792 | " \n", 1793 | " \n", 1794 | " \n", 1795 | " \n", 1796 | " \n", 1797 | " \n", 1798 | " \n", 1799 | " \n", 1800 | " \n", 1801 | " \n", 1802 | " \n", 1803 | " \n", 1804 | " \n", 1805 | " \n", 1806 | " \n", 1807 | " \n", 1808 | " \n", 1809 | " \n", 1810 | " \n", 1811 | " \n", 1812 | " \n", 1813 | " \n", 1814 | " \n", 1815 | " \n", 1816 | " \n", 1817 | " \n", 1818 | " \n", 1819 | " \n", 1820 | " \n", 1821 | " \n", 1822 | " \n", 1823 | " \n", 1824 | " \n", 1825 | " \n", 1826 | " \n", 1827 | " \n", 1828 | " \n", 1829 | " \n", 1830 | " \n", 1831 | " \n", 1832 | " \n", 1833 | " \n", 1834 | " \n", 1835 | " \n", 1836 | " \n", 1837 | " \n", 1838 | " \n", 1839 | " \n", 1840 | " \n", 1841 | " \n", 1842 | " \n", 1843 | " \n", 1844 | " \n", 1845 | " \n", 1846 | " \n", 1847 | " \n", 1848 | " \n", 1849 | " \n", 1850 | " \n", 1851 | " \n", 1852 | " \n", 1853 | " \n", 1854 | " \n", 1855 | " \n", 1856 | " \n", 1857 | " \n", 1858 | " \n", 1859 | " \n", 1860 | " \n", 1861 | " \n", 1862 | " \n", 1863 | " \n", 1864 | " \n", 1865 | " \n", 1866 | " \n", 1867 | " \n", 1868 | " \n", 1869 | " \n", 1870 | " \n", 1871 | " \n", 1872 | " \n", 1873 | " \n", 1874 | " \n", 1875 | " \n", 1876 | " \n", 1877 | " \n", 1878 | " \n", 1879 | " \n", 1880 | " \n", 1881 | " \n", 1882 | " \n", 1883 | " \n", 1884 | " \n", 1885 | " \n", 1886 | " \n", 1887 | " \n", 1888 | " \n", 1889 | " \n", 1890 | " \n", 1891 | " \n", 1892 | " \n", 1893 | " \n", 1894 | " \n", 1895 | " \n", 1896 | " \n", 1897 | " \n", 1898 | " \n", 1899 | " \n", 1900 | " \n", 1901 | " \n", 1902 | " \n", 1903 | " \n", 1904 | " \n", 1905 | " \n", 1906 | " \n", 1907 | " \n", 1908 | " \n", 1909 | " \n", 1910 | " \n", 1911 | " \n", 1912 | " \n", 1913 | " \n", 1914 | " \n", 1915 | " \n", 1916 | " \n", 1917 | " \n", 1918 | " \n", 1919 | " \n", 1920 | " \n", 1921 | " \n", 1922 | " \n", 1923 | " \n", 1924 | " \n", 1925 | " \n", 1926 | " \n", 1927 | " \n", 1928 | " \n", 1929 | " \n", 1930 | " \n", 1931 | " \n", 1932 | " \n", 1933 | " \n", 1934 | " \n", 1935 | " \n", 1936 | " \n", 1937 | " \n", 1938 | " \n", 1939 | " \n", 1940 | " \n", 1941 | " \n", 1942 | " \n", 1943 | " \n", 1944 | " \n", 1945 | " \n", 1946 | " \n", 1947 | " \n", 1948 | " \n", 1949 | " \n", 1950 | " \n", 1951 | " \n", 1952 | " \n", 1953 | " \n", 1954 | " \n", 1955 | " \n", 1956 | " \n", 1957 | " \n", 1958 | "
time_keytime_label_24time_label_12time_interval_15mintime_interval_30mintime_interval_60minlabel_hhlabel_hh24label_15min_24label_30min_24label_60min_24label_15min_12label_30min_12label_60min_12minute_after_hour
0000:0012:00 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM0
1100:0112:01 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM1
2200:0212:02 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM2
3300:0312:03 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM3
4400:0412:04 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM4
5500:0512:05 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM5
6600:0612:06 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM6
7700:0712:07 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM7
8800:0812:08 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM8
9900:0912:09 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM9
101000:1012:10 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM10
111100:1112:11 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM11
121200:1212:12 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM12
131300:1312:13 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM13
141400:1412:14 AM00012 AM0000:0000:0000:0012:00 AM12:00 AM12:00 AM14
151500:1512:15 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM15
161600:1612:16 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM16
171700:1712:17 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM17
181800:1812:18 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM18
191900:1912:19 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM19
202000:2012:20 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM20
212100:2112:21 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM21
222200:2212:22 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM22
232300:2312:23 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM23
242400:2412:24 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM24
252500:2512:25 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM25
262600:2612:26 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM26
272700:2712:27 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM27
282800:2812:28 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM28
292900:2912:29 AM10012 AM0000:1500:0000:0012:15 AM12:00 AM12:00 AM29
................................................
707001:1001:10 AM42101 AM0101:0001:0001:0001:00 AM01:00 AM01:00 AM10
717101:1101:11 AM42101 AM0101:0001:0001:0001:00 AM01:00 AM01:00 AM11
727201:1201:12 AM42101 AM0101:0001:0001:0001:00 AM01:00 AM01:00 AM12
737301:1301:13 AM42101 AM0101:0001:0001:0001:00 AM01:00 AM01:00 AM13
747401:1401:14 AM42101 AM0101:0001:0001:0001:00 AM01:00 AM01:00 AM14
757501:1501:15 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM15
767601:1601:16 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM16
777701:1701:17 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM17
787801:1801:18 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM18
797901:1901:19 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM19
808001:2001:20 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM20
818101:2101:21 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM21
828201:2201:22 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM22
838301:2301:23 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM23
848401:2401:24 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM24
858501:2501:25 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM25
868601:2601:26 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM26
878701:2701:27 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM27
888801:2801:28 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM28
898901:2901:29 AM52101 AM0101:1501:0001:0001:15 AM01:00 AM01:00 AM29
909001:3001:30 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM30
919101:3101:31 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM31
929201:3201:32 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM32
939301:3301:33 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM33
949401:3401:34 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM34
959501:3501:35 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM35
969601:3601:36 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM36
979701:3701:37 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM37
989801:3801:38 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM38
999901:3901:39 AM63101 AM0101:3001:3001:0001:30 AM01:30 AM01:00 AM39
\n", 1959 | "

100 rows × 15 columns

\n", 1960 | "
" 1961 | ], 1962 | "text/plain": [ 1963 | " time_key time_label_24 time_label_12 time_interval_15min \\\n", 1964 | "0 0 00:00 12:00 AM 0 \n", 1965 | "1 1 00:01 12:01 AM 0 \n", 1966 | "2 2 00:02 12:02 AM 0 \n", 1967 | "3 3 00:03 12:03 AM 0 \n", 1968 | "4 4 00:04 12:04 AM 0 \n", 1969 | "5 5 00:05 12:05 AM 0 \n", 1970 | "6 6 00:06 12:06 AM 0 \n", 1971 | "7 7 00:07 12:07 AM 0 \n", 1972 | "8 8 00:08 12:08 AM 0 \n", 1973 | "9 9 00:09 12:09 AM 0 \n", 1974 | "10 10 00:10 12:10 AM 0 \n", 1975 | "11 11 00:11 12:11 AM 0 \n", 1976 | "12 12 00:12 12:12 AM 0 \n", 1977 | "13 13 00:13 12:13 AM 0 \n", 1978 | "14 14 00:14 12:14 AM 0 \n", 1979 | "15 15 00:15 12:15 AM 1 \n", 1980 | "16 16 00:16 12:16 AM 1 \n", 1981 | "17 17 00:17 12:17 AM 1 \n", 1982 | "18 18 00:18 12:18 AM 1 \n", 1983 | "19 19 00:19 12:19 AM 1 \n", 1984 | "20 20 00:20 12:20 AM 1 \n", 1985 | "21 21 00:21 12:21 AM 1 \n", 1986 | "22 22 00:22 12:22 AM 1 \n", 1987 | "23 23 00:23 12:23 AM 1 \n", 1988 | "24 24 00:24 12:24 AM 1 \n", 1989 | "25 25 00:25 12:25 AM 1 \n", 1990 | "26 26 00:26 12:26 AM 1 \n", 1991 | "27 27 00:27 12:27 AM 1 \n", 1992 | "28 28 00:28 12:28 AM 1 \n", 1993 | "29 29 00:29 12:29 AM 1 \n", 1994 | ".. ... ... ... ... \n", 1995 | "70 70 01:10 01:10 AM 4 \n", 1996 | "71 71 01:11 01:11 AM 4 \n", 1997 | "72 72 01:12 01:12 AM 4 \n", 1998 | "73 73 01:13 01:13 AM 4 \n", 1999 | "74 74 01:14 01:14 AM 4 \n", 2000 | "75 75 01:15 01:15 AM 5 \n", 2001 | "76 76 01:16 01:16 AM 5 \n", 2002 | "77 77 01:17 01:17 AM 5 \n", 2003 | "78 78 01:18 01:18 AM 5 \n", 2004 | "79 79 01:19 01:19 AM 5 \n", 2005 | "80 80 01:20 01:20 AM 5 \n", 2006 | "81 81 01:21 01:21 AM 5 \n", 2007 | "82 82 01:22 01:22 AM 5 \n", 2008 | "83 83 01:23 01:23 AM 5 \n", 2009 | "84 84 01:24 01:24 AM 5 \n", 2010 | "85 85 01:25 01:25 AM 5 \n", 2011 | "86 86 01:26 01:26 AM 5 \n", 2012 | "87 87 01:27 01:27 AM 5 \n", 2013 | "88 88 01:28 01:28 AM 5 \n", 2014 | "89 89 01:29 01:29 AM 5 \n", 2015 | "90 90 01:30 01:30 AM 6 \n", 2016 | "91 91 01:31 01:31 AM 6 \n", 2017 | "92 92 01:32 01:32 AM 6 \n", 2018 | "93 93 01:33 01:33 AM 6 \n", 2019 | "94 94 01:34 01:34 AM 6 \n", 2020 | "95 95 01:35 01:35 AM 6 \n", 2021 | "96 96 01:36 01:36 AM 6 \n", 2022 | "97 97 01:37 01:37 AM 6 \n", 2023 | "98 98 01:38 01:38 AM 6 \n", 2024 | "99 99 01:39 01:39 AM 6 \n", 2025 | "\n", 2026 | " time_interval_30min time_interval_60min label_hh label_hh24 \\\n", 2027 | "0 0 0 12 AM 00 \n", 2028 | "1 0 0 12 AM 00 \n", 2029 | "2 0 0 12 AM 00 \n", 2030 | "3 0 0 12 AM 00 \n", 2031 | "4 0 0 12 AM 00 \n", 2032 | "5 0 0 12 AM 00 \n", 2033 | "6 0 0 12 AM 00 \n", 2034 | "7 0 0 12 AM 00 \n", 2035 | "8 0 0 12 AM 00 \n", 2036 | "9 0 0 12 AM 00 \n", 2037 | "10 0 0 12 AM 00 \n", 2038 | "11 0 0 12 AM 00 \n", 2039 | "12 0 0 12 AM 00 \n", 2040 | "13 0 0 12 AM 00 \n", 2041 | "14 0 0 12 AM 00 \n", 2042 | "15 0 0 12 AM 00 \n", 2043 | "16 0 0 12 AM 00 \n", 2044 | "17 0 0 12 AM 00 \n", 2045 | "18 0 0 12 AM 00 \n", 2046 | "19 0 0 12 AM 00 \n", 2047 | "20 0 0 12 AM 00 \n", 2048 | "21 0 0 12 AM 00 \n", 2049 | "22 0 0 12 AM 00 \n", 2050 | "23 0 0 12 AM 00 \n", 2051 | "24 0 0 12 AM 00 \n", 2052 | "25 0 0 12 AM 00 \n", 2053 | "26 0 0 12 AM 00 \n", 2054 | "27 0 0 12 AM 00 \n", 2055 | "28 0 0 12 AM 00 \n", 2056 | "29 0 0 12 AM 00 \n", 2057 | ".. ... ... ... ... \n", 2058 | "70 2 1 01 AM 01 \n", 2059 | "71 2 1 01 AM 01 \n", 2060 | "72 2 1 01 AM 01 \n", 2061 | "73 2 1 01 AM 01 \n", 2062 | "74 2 1 01 AM 01 \n", 2063 | "75 2 1 01 AM 01 \n", 2064 | "76 2 1 01 AM 01 \n", 2065 | "77 2 1 01 AM 01 \n", 2066 | "78 2 1 01 AM 01 \n", 2067 | "79 2 1 01 AM 01 \n", 2068 | "80 2 1 01 AM 01 \n", 2069 | "81 2 1 01 AM 01 \n", 2070 | "82 2 1 01 AM 01 \n", 2071 | "83 2 1 01 AM 01 \n", 2072 | "84 2 1 01 AM 01 \n", 2073 | "85 2 1 01 AM 01 \n", 2074 | "86 2 1 01 AM 01 \n", 2075 | "87 2 1 01 AM 01 \n", 2076 | "88 2 1 01 AM 01 \n", 2077 | "89 2 1 01 AM 01 \n", 2078 | "90 3 1 01 AM 01 \n", 2079 | "91 3 1 01 AM 01 \n", 2080 | "92 3 1 01 AM 01 \n", 2081 | "93 3 1 01 AM 01 \n", 2082 | "94 3 1 01 AM 01 \n", 2083 | "95 3 1 01 AM 01 \n", 2084 | "96 3 1 01 AM 01 \n", 2085 | "97 3 1 01 AM 01 \n", 2086 | "98 3 1 01 AM 01 \n", 2087 | "99 3 1 01 AM 01 \n", 2088 | "\n", 2089 | " label_15min_24 label_30min_24 label_60min_24 label_15min_12 label_30min_12 \\\n", 2090 | "0 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2091 | "1 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2092 | "2 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2093 | "3 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2094 | "4 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2095 | "5 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2096 | "6 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2097 | "7 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2098 | "8 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2099 | "9 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2100 | "10 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2101 | "11 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2102 | "12 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2103 | "13 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2104 | "14 00:00 00:00 00:00 12:00 AM 12:00 AM \n", 2105 | "15 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2106 | "16 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2107 | "17 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2108 | "18 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2109 | "19 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2110 | "20 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2111 | "21 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2112 | "22 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2113 | "23 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2114 | "24 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2115 | "25 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2116 | "26 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2117 | "27 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2118 | "28 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2119 | "29 00:15 00:00 00:00 12:15 AM 12:00 AM \n", 2120 | ".. ... ... ... ... ... \n", 2121 | "70 01:00 01:00 01:00 01:00 AM 01:00 AM \n", 2122 | "71 01:00 01:00 01:00 01:00 AM 01:00 AM \n", 2123 | "72 01:00 01:00 01:00 01:00 AM 01:00 AM \n", 2124 | "73 01:00 01:00 01:00 01:00 AM 01:00 AM \n", 2125 | "74 01:00 01:00 01:00 01:00 AM 01:00 AM \n", 2126 | "75 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2127 | "76 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2128 | "77 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2129 | "78 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2130 | "79 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2131 | "80 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2132 | "81 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2133 | "82 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2134 | "83 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2135 | "84 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2136 | "85 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2137 | "86 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2138 | "87 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2139 | "88 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2140 | "89 01:15 01:00 01:00 01:15 AM 01:00 AM \n", 2141 | "90 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2142 | "91 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2143 | "92 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2144 | "93 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2145 | "94 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2146 | "95 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2147 | "96 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2148 | "97 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2149 | "98 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2150 | "99 01:30 01:30 01:00 01:30 AM 01:30 AM \n", 2151 | "\n", 2152 | " label_60min_12 minute_after_hour \n", 2153 | "0 12:00 AM 0 \n", 2154 | "1 12:00 AM 1 \n", 2155 | "2 12:00 AM 2 \n", 2156 | "3 12:00 AM 3 \n", 2157 | "4 12:00 AM 4 \n", 2158 | "5 12:00 AM 5 \n", 2159 | "6 12:00 AM 6 \n", 2160 | "7 12:00 AM 7 \n", 2161 | "8 12:00 AM 8 \n", 2162 | "9 12:00 AM 9 \n", 2163 | "10 12:00 AM 10 \n", 2164 | "11 12:00 AM 11 \n", 2165 | "12 12:00 AM 12 \n", 2166 | "13 12:00 AM 13 \n", 2167 | "14 12:00 AM 14 \n", 2168 | "15 12:00 AM 15 \n", 2169 | "16 12:00 AM 16 \n", 2170 | "17 12:00 AM 17 \n", 2171 | "18 12:00 AM 18 \n", 2172 | "19 12:00 AM 19 \n", 2173 | "20 12:00 AM 20 \n", 2174 | "21 12:00 AM 21 \n", 2175 | "22 12:00 AM 22 \n", 2176 | "23 12:00 AM 23 \n", 2177 | "24 12:00 AM 24 \n", 2178 | "25 12:00 AM 25 \n", 2179 | "26 12:00 AM 26 \n", 2180 | "27 12:00 AM 27 \n", 2181 | "28 12:00 AM 28 \n", 2182 | "29 12:00 AM 29 \n", 2183 | ".. ... ... \n", 2184 | "70 01:00 AM 10 \n", 2185 | "71 01:00 AM 11 \n", 2186 | "72 01:00 AM 12 \n", 2187 | "73 01:00 AM 13 \n", 2188 | "74 01:00 AM 14 \n", 2189 | "75 01:00 AM 15 \n", 2190 | "76 01:00 AM 16 \n", 2191 | "77 01:00 AM 17 \n", 2192 | "78 01:00 AM 18 \n", 2193 | "79 01:00 AM 19 \n", 2194 | "80 01:00 AM 20 \n", 2195 | "81 01:00 AM 21 \n", 2196 | "82 01:00 AM 22 \n", 2197 | "83 01:00 AM 23 \n", 2198 | "84 01:00 AM 24 \n", 2199 | "85 01:00 AM 25 \n", 2200 | "86 01:00 AM 26 \n", 2201 | "87 01:00 AM 27 \n", 2202 | "88 01:00 AM 28 \n", 2203 | "89 01:00 AM 29 \n", 2204 | "90 01:00 AM 30 \n", 2205 | "91 01:00 AM 31 \n", 2206 | "92 01:00 AM 32 \n", 2207 | "93 01:00 AM 33 \n", 2208 | "94 01:00 AM 34 \n", 2209 | "95 01:00 AM 35 \n", 2210 | "96 01:00 AM 36 \n", 2211 | "97 01:00 AM 37 \n", 2212 | "98 01:00 AM 38 \n", 2213 | "99 01:00 AM 39 \n", 2214 | "\n", 2215 | "[100 rows x 15 columns]" 2216 | ] 2217 | }, 2218 | "execution_count": 32, 2219 | "metadata": {}, 2220 | "output_type": "execute_result" 2221 | } 2222 | ], 2223 | "source": [ 2224 | "time_dim.head(n=100)" 2225 | ] 2226 | }, 2227 | { 2228 | "cell_type": "code", 2229 | "execution_count": 72, 2230 | "metadata": { 2231 | "collapsed": false 2232 | }, 2233 | "outputs": [], 2234 | "source": [ 2235 | "## Export each to a CSV first so that we can use the COPY command. It's substantially more efficient.\n", 2236 | "# date_dim.to_csv(path_or_buf=\"./date_dim.csv\", index=False)\n", 2237 | "time_dim.to_csv(path_or_buf=\"./time_dim.csv\", index=False)" 2238 | ] 2239 | }, 2240 | { 2241 | "cell_type": "markdown", 2242 | "metadata": {}, 2243 | "source": [ 2244 | "### Create the database table the lazy way\n", 2245 | "We want to load the data from the CSV to save time, but we also want to programmatically create the table in postgres. This simply takes our dataframe, removes all the data but keeps the column names, and uses that to create the table. It also gives them appropriate data types (most of the time). Then, we fill the table with a copy command." 2246 | ] 2247 | }, 2248 | { 2249 | "cell_type": "code", 2250 | "execution_count": 39, 2251 | "metadata": { 2252 | "collapsed": false 2253 | }, 2254 | "outputs": [], 2255 | "source": [ 2256 | "engine = create_engine('postgresql://' + username + ':' + password + '@' + host + '/' + db_name)" 2257 | ] 2258 | }, 2259 | { 2260 | "cell_type": "code", 2261 | "execution_count": 48, 2262 | "metadata": { 2263 | "collapsed": false 2264 | }, 2265 | "outputs": [], 2266 | "source": [ 2267 | "empty_date_dim = date_dim.copy()\n", 2268 | "empty_date_dim = empty_date_dim.drop(empty_date_dim.index[0:date_dim.shape[0]])\n", 2269 | "empty_date_dim.to_sql(\"date_dimension\", engine, if_exists=\"replace\", index=False)" 2270 | ] 2271 | }, 2272 | { 2273 | "cell_type": "code", 2274 | "execution_count": 73, 2275 | "metadata": { 2276 | "collapsed": false 2277 | }, 2278 | "outputs": [], 2279 | "source": [ 2280 | "empty_time_dim = time_dim.copy()\n", 2281 | "empty_time_dim = empty_time_dim.drop(empty_time_dim.index[0:time_dim.shape[0]])\n", 2282 | "empty_time_dim.to_sql(\"time_dimension\", engine, if_exists=\"replace\", index=False)" 2283 | ] 2284 | }, 2285 | { 2286 | "cell_type": "markdown", 2287 | "metadata": {}, 2288 | "source": [ 2289 | "We have to create a new connection here. The above uses sqlalchemy, which then itself uses psycopg2, but we want to use psycopg2 directly." 2290 | ] 2291 | }, 2292 | { 2293 | "cell_type": "code", 2294 | "execution_count": 74, 2295 | "metadata": { 2296 | "collapsed": false 2297 | }, 2298 | "outputs": [], 2299 | "source": [ 2300 | "connection_string = \"dbname='\" + db_name + \"' \"\n", 2301 | "connection_string += \"user='\" + username + \"' \"\n", 2302 | "connection_string += \"host='\" + host + \"' \"\n", 2303 | "connection_string += \"password='\" + password + \"' \"" 2304 | ] 2305 | }, 2306 | { 2307 | "cell_type": "code", 2308 | "execution_count": 75, 2309 | "metadata": { 2310 | "collapsed": true 2311 | }, 2312 | "outputs": [], 2313 | "source": [ 2314 | "# Set up a copy statement. The %s will be replaced later\n", 2315 | "sql_statement = \"\"\"\n", 2316 | " COPY %s FROM STDIN WITH\n", 2317 | " CSV\n", 2318 | " HEADER\n", 2319 | " DELIMITER AS ','\n", 2320 | "\"\"\"" 2321 | ] 2322 | }, 2323 | { 2324 | "cell_type": "code", 2325 | "execution_count": 76, 2326 | "metadata": { 2327 | "collapsed": true 2328 | }, 2329 | "outputs": [], 2330 | "source": [ 2331 | "def load_file(conn, table_name, primary_key, file_object):\n", 2332 | " cursor = conn.cursor()\n", 2333 | " cursor.copy_expert(sql=sql_statement % table_name, file=file_object)\n", 2334 | " conn.commit()\n", 2335 | " \n", 2336 | " # Add add primary key, index and then vacuum \n", 2337 | " cursor.execute(\"ALTER TABLE \" + table_name + \" ADD PRIMARY KEY (\" + primary_key + \")\")\n", 2338 | " cursor.execute(\"VACUUM VERBOSE ANALYZE \" + table_name)\n", 2339 | " cursor.execute(\"CREATE INDEX ON \" + table_name + \" (\" + primary_key + \" ASC NULLS LAST);\")\n", 2340 | " cursor.close()" 2341 | ] 2342 | }, 2343 | { 2344 | "cell_type": "code", 2345 | "execution_count": 53, 2346 | "metadata": { 2347 | "collapsed": false 2348 | }, 2349 | "outputs": [ 2350 | { 2351 | "data": { 2352 | "text/plain": [ 2353 | "" 2354 | ] 2355 | }, 2356 | "execution_count": 53, 2357 | "metadata": {}, 2358 | "output_type": "execute_result" 2359 | } 2360 | ], 2361 | "source": [ 2362 | "date_dim_file = open(\"./date_dim.csv\")\n", 2363 | "date_dim_file" 2364 | ] 2365 | }, 2366 | { 2367 | "cell_type": "code", 2368 | "execution_count": 57, 2369 | "metadata": { 2370 | "collapsed": false 2371 | }, 2372 | "outputs": [ 2373 | { 2374 | "ename": "NameError", 2375 | "evalue": "name 'date_dim_file' is not defined", 2376 | "output_type": "error", 2377 | "traceback": [ 2378 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 2379 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 2380 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mconn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautocommit\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mload_file\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtable_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'date_dimension'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprimary_key\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"date_key\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfile_object\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdate_dim_file\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;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mconn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 2381 | "\u001b[0;31mNameError\u001b[0m: name 'date_dim_file' is not defined" 2382 | ] 2383 | } 2384 | ], 2385 | "source": [ 2386 | "conn = psycopg2.connect(connection_string)\n", 2387 | "conn.autocommit = True\n", 2388 | "try:\n", 2389 | " load_file(conn, table_name='date_dimension', primary_key=\"date_key\", file_object=date_dim_file)\n", 2390 | "finally:\n", 2391 | " conn.close()" 2392 | ] 2393 | }, 2394 | { 2395 | "cell_type": "code", 2396 | "execution_count": 77, 2397 | "metadata": { 2398 | "collapsed": false 2399 | }, 2400 | "outputs": [ 2401 | { 2402 | "data": { 2403 | "text/plain": [ 2404 | "" 2405 | ] 2406 | }, 2407 | "execution_count": 77, 2408 | "metadata": {}, 2409 | "output_type": "execute_result" 2410 | } 2411 | ], 2412 | "source": [ 2413 | "time_dim_file = open(\"./time_dim.csv\")\n", 2414 | "time_dim_file" 2415 | ] 2416 | }, 2417 | { 2418 | "cell_type": "code", 2419 | "execution_count": 78, 2420 | "metadata": { 2421 | "collapsed": false 2422 | }, 2423 | "outputs": [], 2424 | "source": [ 2425 | "conn = psycopg2.connect(connection_string)\n", 2426 | "conn.autocommit = True\n", 2427 | "try:\n", 2428 | " load_file(conn, table_name='time_dimension', primary_key=\"time_key\", file_object=time_dim_file)\n", 2429 | "finally:\n", 2430 | " conn.close()" 2431 | ] 2432 | }, 2433 | { 2434 | "cell_type": "code", 2435 | "execution_count": 16, 2436 | "metadata": { 2437 | "collapsed": false 2438 | }, 2439 | "outputs": [], 2440 | "source": [ 2441 | "pokemon_info_df = pd.read_csv(filepath_or_buffer=\"./dimension_table_csvs/pokemon_info.csv\")\n", 2442 | "empty_pokemon_pk_info = pokemon_info_df.copy()\n", 2443 | "empty_pokemon_pk_info = empty_pokemon_pk_info.drop(empty_pokemon_pk_info.index[0:empty_pokemon_pk_info.shape[0]])\n", 2444 | "empty_pokemon_pk_info.to_sql(\"pokemon_info\", engine, if_exists=\"replace\", index=False)" 2445 | ] 2446 | }, 2447 | { 2448 | "cell_type": "code", 2449 | "execution_count": 17, 2450 | "metadata": { 2451 | "collapsed": false 2452 | }, 2453 | "outputs": [ 2454 | { 2455 | "data": { 2456 | "text/plain": [ 2457 | "" 2458 | ] 2459 | }, 2460 | "execution_count": 17, 2461 | "metadata": {}, 2462 | "output_type": "execute_result" 2463 | } 2464 | ], 2465 | "source": [ 2466 | "pokemon_info_dim_file = open(\"./dimension_table_csvs/pokemon_info.csv\")\n", 2467 | "pokemon_info_dim_file" 2468 | ] 2469 | }, 2470 | { 2471 | "cell_type": "code", 2472 | "execution_count": 18, 2473 | "metadata": { 2474 | "collapsed": false 2475 | }, 2476 | "outputs": [], 2477 | "source": [ 2478 | "conn = psycopg2.connect(connection_string)\n", 2479 | "conn.autocommit = True\n", 2480 | "try:\n", 2481 | " load_file(conn, table_name='pokemon_info', primary_key=\"pokemon_id\", file_object=pokemon_info_dim_file)\n", 2482 | "finally:\n", 2483 | " conn.close()" 2484 | ] 2485 | }, 2486 | { 2487 | "cell_type": "code", 2488 | "execution_count": null, 2489 | "metadata": { 2490 | "collapsed": true 2491 | }, 2492 | "outputs": [], 2493 | "source": [] 2494 | } 2495 | ], 2496 | "metadata": { 2497 | "kernelspec": { 2498 | "display_name": "Python 2", 2499 | "language": "python", 2500 | "name": "python2" 2501 | }, 2502 | "language_info": { 2503 | "codemirror_mode": { 2504 | "name": "ipython", 2505 | "version": 2 2506 | }, 2507 | "file_extension": ".py", 2508 | "mimetype": "text/x-python", 2509 | "name": "python", 2510 | "nbconvert_exporter": "python", 2511 | "pygments_lexer": "ipython2", 2512 | "version": "2.7.9" 2513 | } 2514 | }, 2515 | "nbformat": 4, 2516 | "nbformat_minor": 0 2517 | } 2518 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Ryan Brideau 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pokelyzer 2 | 3 | A webhook listener and database schema for doing geospatial analysis and advanced analytics on Pokemon Go data. 4 | 5 | ![Tableau Screenshot of Spawn Points](http://i.imgur.com/xRY8bLn.png) 6 | 7 | ## Explanation 8 | 9 | These blog posts help to explain what Pokelyzer is, and what it can be used for. 10 | 11 | - [The Original Concept](http://www.whackdata.com/2016/07/25/tool-for-analyzing-mapping-pokemon-go/) 12 | - [Finding Hotpots for Locally Rare Pokemon Using Tableau](http://www.whackdata.com/2016/07/27/finding-locally-rare-pokemon/) 13 | - [Help Others Find Rare Pokemon Nearby](http://www.whackdata.com/2016/07/29/help-others-find-rare-pokemon-nearby/) 14 | 15 | ## The Database Schema 16 | 17 | The schema itself follows the approach of dimensional modelling to keep it fast and flexible. The entire schema currently looks like this: 18 | 19 | ![Schema image](http://i.imgur.com/y8580i4.png) 20 | 21 | It looks like a lot, but it isn't. `spotted_pokemon` is where all your data goes. The `date_dimension` and `time_dimension` tables let you slice and filter by dates and times, and the `pokemon_info` table lets you do the same with Pokemon information. `_meta` keeps track of changes to the schema itself. `date_dimension`, `time_dimension`, `pokemon_info` and `_meta` all connect to the `spotted_pokemon` table. 22 | 23 | ## The Webhook Listener 24 | 25 | The webhook listener is a node application that listens for POSTS to port 9876 by default, for JSON messages that look like this: 26 | 27 | ```javascript 28 | { 29 | "type": "pokemon", 30 | "message": { 31 | "encounter_id": "17290083747243295117", 32 | "spawnpoint_id": "4ca42277a41", 33 | "pokemon_id": "41", 34 | "latitude": "45.9586350970765", 35 | "longitude": "-66.6595416124465", 36 | "disappear_time": "1469421912", 37 | "last_modified_time": "1469421858380", 38 | "time_until_hidden_ms": "54456" 39 | } 40 | } 41 | ``` 42 | 43 | Where timestamps are in UNIX time. If you are manually submitting data to this endpoint, pass in an additional parameter `ENC_ENC=f` (`set ENC_ENC=f` on Windows) to ensure that it does not try to decode the `encounter_id`, which it has to for the PokemonGo-Map data source. 44 | 45 | ## Installation 46 | 47 | See the [wiki page](https://github.com/Brideau/pokelyzer/wiki) for installation instructions. 48 | 49 | ## Upgrading 50 | 51 | If you already have the database running, ensure all of the patches below since your installation date have been applied. I wish there were better version control for databases, but this is the best solution I have for now. If you know of a better one, let me know. 52 | 53 | To use the webhook listener, I recommend doing a fresh installation of PokemonGo-Map using the instructions prodvided in [the wiki ](https://github.com/Brideau/pokelyzer/wiki). Just rename your current directory to something else and do the install. No data will be lost from Pokelyzer since that's stored separately from the PokemonGo-Map database. 54 | 55 | ## Patches 56 | 57 | Before you try to do recent tutorials or install new versions of the webhook listener, please install all patches **since your installation date**. 58 | 59 | All patches can be found in the [Patches wiki page](https://github.com/Brideau/pokelyzer/wiki/Patches). 60 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var bodyParser = require('body-parser'); 3 | var moment = require('moment') 4 | 5 | var gaussian = require('gaussian'); 6 | var dist = gaussian(0, 0.3); 7 | 8 | var configFile = require('./config'); 9 | // Set up Postgres connection 10 | var pg = require('pg'); 11 | var config = { 12 | user: process.env.DB_USER || configFile.DB_USER, 13 | database: process.env.DB_NAME || configFile.DB_NAME, 14 | password: process.env.DB_PASS || configFile.DB_PASS, 15 | port: process.env.DB_PORT || configFile.DB_PORT, 16 | max: 20, 17 | idleTimeoutMillis: 30000 18 | } 19 | var pool = new pg.Pool(config); 20 | var encounter_encoded = process.env.ENC_ENC || configFile.ENC_ENC; 21 | 22 | var app = express(); 23 | app.use(bodyParser.urlencoded({extended : true})); 24 | app.use(bodyParser.json()); 25 | 26 | var server = require('http').Server(app); 27 | var port = process.env.WS_PORT || configFile.WS_PORT; 28 | var era = process.env.ERA || configFile.ERA; 29 | 30 | server.listen(port, function (err) { 31 | console.info('Running server on port ' + port); 32 | }); 33 | 34 | app.post('/', function(req, res) { 35 | var body = req.body; 36 | if (body.type == "pokemon") { 37 | var m = body.message; 38 | m.pokemon_go_era = era; 39 | m.hidden_time_unix_s = m.disappear_time; 40 | m.hidden_time_utc = moment 41 | .unix(m.hidden_time_unix_s).utc() 42 | .format("YYYY-MM-DD HH:mm:ss"); 43 | m.latitude_jittered = parseFloat(m.latitude) + dist.ppf(Math.random()) * 0.0005; 44 | m.longitude_jittered = parseFloat(m.longitude) + dist.ppf(Math.random()) * 0.0005; 45 | if (m.is_lured == true) { 46 | m.time_until_hidden_ms = null; 47 | m.is_lured = "Lured"; 48 | } else { 49 | m.is_lured = "Not Lured"; 50 | } 51 | 52 | if (encounter_encoded == "t") { 53 | buff = new Buffer(m.encounter_id, 'base64'); 54 | m.encounter_id = buff.toString(); 55 | } 56 | // console.log(m); 57 | pool.connect(function(err, client, done) { 58 | if(err) { 59 | return console.log('Error fetching client from pool', err); 60 | } 61 | 62 | query_string = "INSERT INTO spotted_pokemon ( \ 63 | encounter_id, \ 64 | last_modified_time, \ 65 | time_until_hidden_ms, \ 66 | hidden_time_unix_s, \ 67 | hidden_time_utc, \ 68 | spawnpoint_id, \ 69 | longitude, \ 70 | latitude, \ 71 | pokemon_id, \ 72 | longitude_jittered, \ 73 | latitude_jittered, \ 74 | pokemon_go_era, \ 75 | lured) \ 76 | VALUES ( \ 77 | '" + m.encounter_id + "'::text, \ 78 | " + m.last_modified_time + "::bigint, \ 79 | " + m.time_until_hidden_ms + "::bigint, \ 80 | " + m.hidden_time_unix_s + "::bigint, \ 81 | '" + m.hidden_time_utc + "'::timestamp, \ 82 | '" + m.spawnpoint_id + "'::text, \ 83 | " + m.longitude + "::double precision, \ 84 | " + m.latitude + "::double precision, \ 85 | " + m.pokemon_id + "::smallint, \ 86 | " + m.longitude_jittered + "::double precision, \ 87 | " + m.latitude_jittered + "::double precision, \ 88 | " + m.pokemon_go_era + "::integer, \ 89 | '" + m.is_lured + "'::text \ 90 | ) \ 91 | ON CONFLICT (encounter_id, spawnpoint_id) \ 92 | DO UPDATE \ 93 | SET last_modified_time = EXCLUDED.last_modified_time, \ 94 | time_until_hidden_ms = EXCLUDED.time_until_hidden_ms, \ 95 | hidden_time_unix_s = EXCLUDED.hidden_time_unix_s, \ 96 | hidden_time_utc = EXCLUDED.hidden_time_utc;"; 97 | 98 | // console.log(query_string); 99 | console.log("[" + moment().format() + "] Pokemon with ID " + m.pokemon_id + " found.") 100 | 101 | client.query(query_string, 102 | function(err, result) { 103 | // console.log(result); 104 | done(); 105 | if(err) { 106 | return console.log("Error running query", err); 107 | } 108 | }); 109 | }); 110 | } 111 | res.sendStatus(200); 112 | }); 113 | 114 | pool.on('error', function(err, client) { 115 | console.log('Idle client error', err.message, err.stack); 116 | }); 117 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | var config = {}; 2 | 3 | config.DB_USER = 'pokemon_go_role'; 4 | config.DB_NAME = 'pokemon_go'; 5 | config.DB_PASS = '' 6 | config.DB_PORT = 5432; 7 | config.ENC_ENC = "t"; 8 | config.WS_PORT = 9876; 9 | config.ERA = 3; 10 | 11 | module.exports = config; 12 | -------------------------------------------------------------------------------- /dimension_table_csvs/pokemon_info.csv: -------------------------------------------------------------------------------- 1 | pokemon_id,name,classification,type_1,type_2,weight,height,rarity 2 | 1,Bulbasaur,Seed Pokémon,Grass,Poison,6.9,0.7,Uncommon 3 | 2,Ivysaur,Seed Pokémon,Grass,Poison,13,1,Special 4 | 3,Venusaur,Seed Pokémon,Grass,Poison,1,2,Epic 5 | 4,Charmander,Lizard Pokémon,Fire,N/A,8.5,0.6,Uncommon 6 | 5,Charmeleon,Flame Pokémon,Fire,N/A,19,1.1,Special 7 | 6,Charizard,Flame Pokémon,Fire,Flying,90.5,1.7,Epic 8 | 7,Squirtle,Tiny Turtle Pokémon,Water,N/A,9,0.5,Uncommon 9 | 8,Wartortle,Turtle Pokémon,Water,N/A,22.5,1,Special 10 | 9,Blastoise,Shellfish Pokémon,Water,N/A,85.5,1.6,Epic 11 | 10,Caterpie,Worm Pokémon,Bug,N/A,2.9,0.3,Very Common 12 | 11,Metapod,Cocoon Pokémon,Bug,N/A,9.9,0.7,Common 13 | 12,Butterfree,Butterfly Pokémon,Bug,Flying,32,1.1,Uncommon 14 | 13,Weedle,Hairy Pokémon,Bug,Poison,3.2,0.3,Very Common 15 | 14,Kakuna,Cocoon Pokémon,Bug,Poison,10,0.6,Common 16 | 15,Beedrill,Poison Bee Pokémon,Bug,Poison,29.5,1,Uncommon 17 | 16,Pidgey,Tiny Bird Pokémon,Normal,Flying,1.8,0.3,Very Common 18 | 17,Pidgeotto,Bird Pokémon,Normal,Flying,30,1.1,Common 19 | 18,Pidgeot,Bird Pokémon,Normal,Flying,39.5,1.5,Uncommon 20 | 19,Rattata,Mouse Pokémon,Normal,N/A,3.5,0.3,Very Common 21 | 20,Raticate,Mouse Pokémon,Normal,N/A,18.5,0.7,Common 22 | 21,Spearow,Tiny Bird Pokémon,Normal,Flying,2,0.3,Very Common 23 | 22,Fearow,Beak Pokémon,Normal,Flying,38,1.2,Uncommon 24 | 23,Ekans,Snake Pokémon,Poison,N/A,6.9,2,Very Common 25 | 24,Arbok,Cobra Pokémon,Poison,N/A,65,3.5,Common 26 | 25,Pikachu,Mouse Pokémon,Electric,N/A,6,0.4,Uncommon 27 | 26,Raichu,Mouse Pokémon,Electric,N/A,30,0.8,Very Rare 28 | 27,Sandshrew,Mouse Pokémon,Ground,N/A,12,0.6,Very Common 29 | 28,Sandslash,Mouse Pokémon,Ground,N/A,29.5,1,Common 30 | 29,Nidoran F,Poison Pin Pokémon,Poison,N/A,7,0.4,Very Common 31 | 30,Nidorina,Poison Pin Pokémon,Poison,N/A,20,0.8,Uncommon 32 | 31,Nidoqueen,Drill Pokémon,Poison,Ground,60,1.3,Very Rare 33 | 32,Nidoran M,Poison Pin Pokémon,Poison,N/A,9,0.5,Very Common 34 | 33,Nidorino,Poison Pin Pokémon,Poison,N/A,19.5,0.9,Uncommon 35 | 34,Nidoking,Drill Pokémon,Poison,Ground,62,1.4,Very Rare 36 | 35,Clefairy,Fairy Pokémon,Normal,N/A,7.5,0.6,Common 37 | 36,Clefable,Fairy Pokémon,Normal,N/A,40,1.3,Epic 38 | 37,Vulpix,Fox Pokémon,Fire,N/A,9.9,0.6,Common 39 | 38,Ninetales,Fox Pokémon,Fire,N/A,19.9,1.1,Uncommon 40 | 39,Jigglypuff,Balloon Pokémon,Normal,N/A,5.5,0.5,Common 41 | 40,Wigglytuff,Balloon Pokémon,Normal,N/A,12,1,Uncommon 42 | 41,Zubat,Bat Pokémon,Poison,Flying,7.5,0.8,Very Common 43 | 42,Golbat,Bat Pokémon,Poison,Flying,55,1.6,Common 44 | 43,Oddish,Weed Pokémon,Grass,Poison,5.4,0.5,Very Common 45 | 44,Gloom,Weed Pokémon,Grass,Poison,8.6,0.8,Uncommon 46 | 45,Vileplume,Flower Pokémon,Grass,Poison,18.6,1.2,Very Rare 47 | 46,Paras,Mushroom Pokémon,Bug,Grass,5.4,0.3,Very Common 48 | 47,Parasect,Mushroom Pokémon,Bug,Grass,29.5,1,Uncommon 49 | 48,Venonat,Insect Pokémon,Bug,Poison,30,1,Very Common 50 | 49,Venomoth,Poison Moth Pokémon,Bug,Poison,12.5,1.5,Very Rare 51 | 50,Diglett,Mole Pokémon,Ground,N/A,0.8,0.2,Common 52 | 51,Dugtrio,Mole Pokémon,Ground,N/A,33.3,0.7,Uncommon 53 | 52,Meowth,Scratch Cat Pokémon,Normal,N/A,4.2,0.4,Very Common 54 | 53,Persian,Classy Cat Pokémon,Normal,N/A,32,1,Common 55 | 54,Psyduck,Duck Pokémon,Water,N/A,19.6,0.8,Common 56 | 55,Golduck,Duck Pokémon,Water,N/A,76.6,1.7,Uncommon 57 | 56,Mankey,Pig Monkey Pokémon,Fighting,N/A,28,0.5,Very Common 58 | 57,Primeape,Pig Monkey Pokémon,Fighting,N/A,32,1,Uncommon 59 | 58,Growlithe,Puppy Pokémon,Fire,N/A,19,0.7,Common 60 | 59,Arcanine,Legendary Pokémon,Fire,N/A,155,1.9,Rare 61 | 60,Poliwag,Tadpole Pokémon,Water,N/A,12.4,0.6,Very Common 62 | 61,Poliwhirl,Tadpole Pokémon,Water,N/A,20,1,Uncommon 63 | 62,Poliwrath,Tadpole Pokémon,Water,Fighting,54,1.3,Very Rare 64 | 63,Abra,Psi Pokémon,Psychic,N/A,19.5,0.9,Common 65 | 64,Kadabra,Psi Pokémon,Psychic,N/A,56.5,1.3,Uncommon 66 | 65,Alakazam,Psi Pokémon,Psychic,N/A,48,1.5,Very Rare 67 | 66,Machop,Superpower Pokémon,Fighting,N/A,19.5,0.8,Very Common 68 | 67,Machoke,Superpower Pokémon,Fighting,N/A,70.5,1.5,Common 69 | 68,Machamp,Superpower Pokémon,Fighting,N/A,130,1.6,Uncommon 70 | 69,Bellsprout,Flower Pokémon,Grass,Poison,4,0.7,Very Common 71 | 70,Weepinbell,Flycatcher Pokémon,Grass,Poison,6.4,1,Rare 72 | 71,Victreebel,Flycatcher Pokémon,Grass,Poison,15.5,1.7,Very Rare 73 | 72,Tentacool,Jellyfish Pokémon,Water,Poison,45.5,0.9,Common 74 | 73,Tentacruel,Jellyfish Pokémon,Water,Poison,55,1.6,Uncommon 75 | 74,Geodude,Rock Pokémon,Rock,Ground,20,0.4,Very Common 76 | 75,Graveler,Rock Pokémon,Rock,Ground,105,1,Common 77 | 76,Golem,Megaton Pokémon,Rock,Ground,300,1.4,Uncommon 78 | 77,Ponyta,Fire Horse Pokémon,Fire,N/A,30,1,Common 79 | 78,Rapidash,Fire Horse Pokémon,Fire,N/A,95,1.7,Rare 80 | 79,Slowpoke,Dopey Pokémon,Water,Psychic,36,1.2,Very Common 81 | 80,Slowbro,Hermit Crab Pokémon,Water,Psychic,78.5,1.6,Rare 82 | 81,Magnemite,Magnet Pokémon,Electric,Steel,6,0.3,Very Common 83 | 82,Magneton,Magnet Pokémon,Electric,Steel,60,1,Common 84 | 83,Farfetch'd,Wild Duck Pokémon,Normal,Flying,15,0.8,Rare 85 | 84,Doduo,Twin Bird Pokémon,Normal,Flying,39.2,1.4,Common 86 | 85,Dodrio,Triple Bird Pokémon,Normal,Flying,85.2,1.8,Uncommon 87 | 86,Seel,Sea Lion Pokémon,Water,N/A,90,1.1,Common 88 | 87,Dewgong,Sea Lion Pokémon,Water,Ice,120,1.7,Very Rare 89 | 88,Grimer,Sludge Pokémon,Poison,N/A,30,0.9,Common 90 | 89,Muk,Sludge Pokémon,Poison,N/A,30,1.2,Rare 91 | 90,Shellder,Bivalve Pokémon,Water,N/A,4,0.3,Common 92 | 91,Cloyster,Bivalve Pokémon,Water,Ice,132.5,1.5,Uncommon 93 | 92,Gastly,Gas Pokémon,Ghost,Poison,0.1,1.3,Uncommon 94 | 93,Haunter,Gas Pokémon,Ghost,Poison,0.1,1.6,Common 95 | 94,Gengar,Shadow Pokémon,Ghost,Poison,40.5,1.5,Very Rare 96 | 95,Onix,Rock Snake Pokémon,Rock,Ground,210,8.8,Rare 97 | 96,Drowzee,Hypnosis Pokémon,Psychic,N/A,32.4,1,Common 98 | 97,Hypno,Hypnosis Pokémon,Psychic,N/A,75.6,1.6,Uncommon 99 | 98,Krabby,River Crab Pokémon,Water,N/A,6.5,0.4,Very Common 100 | 99,Kingler,Pincer Pokémon,Water,N/A,60,1.3,Rare 101 | 100,Voltorb,Ball Pokémon,Electric,N/A,10.4,0.5,Very Common 102 | 101,Electrode,Ball Pokémon,Electric,N/A,66.6,1.2,Common 103 | 102,Exeggcute,Egg Pokémon,Grass,Psychic,2.5,0.4,Common 104 | 103,Exeggutor,Coconut Pokémon,Grass,Psychic,120,2,Rare 105 | 104,Cubone,Lonely Pokémon,Ground,N/A,6.5,0.4,Common 106 | 105,Marowak,Bone Keeper Pokémon,Ground,N/A,45,1,Very Rare 107 | 106,Hitmonlee,Kicking Pokémon,Fighting,N/A,49.8,1.5,Common 108 | 107,Hitmonchan,Punching Pokémon,Fighting,N/A,50.2,1.4,Uncommon 109 | 108,Lickitung,Licking Pokémon,Normal,N/A,65.5,1.2,Uncommon 110 | 109,Koffing,Poison Gas Pokémon,Poison,N/A,1,0.6,Common 111 | 110,Weezing,Poison Gas Pokémon,Poison,N/A,9.5,1.2,Uncommon 112 | 111,Rhyhorn,Spikes Pokémon,Ground,Rock,115,1,Common 113 | 112,Rhydon,Drill Pokémon,Ground,Rock,120,1.9,Rare 114 | 113,Chansey,Egg Pokémon,Normal,N/A,34.6,1.1,Uncommon 115 | 114,Tangela,Vine Pokémon,Grass,N/A,35,1,Rare 116 | 115,Kangaskhan,Parent Pokémon,Normal,N/A,80,2.2,Very Rare 117 | 116,Horsea,Dragon Pokémon,Water,N/A,8,0.4,Common 118 | 117,Seadra,Dragon Pokémon,Water,N/A,25,1.2,Uncommon 119 | 118,Goldeen,Goldfish Pokémon,Water,N/A,15,0.6,Very Common 120 | 119,Seaking,Goldfish Pokémon,Water,N/A,39,1.3,Uncommon 121 | 120,Staryu,Starshape Pokémon,Water,N/A,34.5,0.8,Common 122 | 121,Starmie,Mysterious Pokémon,Water,Psychic,80,1.1,Uncommon 123 | 122,Mr. Mime,Barrier Pokémon,Psychic,N/A,54.5,1.3,Rare 124 | 123,Scyther,Mantis Pokémon,Bug,Flying,56,1.5,Uncommon 125 | 124,Jynx,Humanshape Pokémon,Ice,Psychic,40.6,1.4,Common 126 | 125,Electabuzz,Electric Pokémon,Electric,N/A,30,1.1,Very Rare 127 | 126,Magmar,Spitfire Pokémon,Fire,N/A,44.5,1.3,Rare 128 | 127,Pinsir,Stagbeetle Pokémon,Bug,N/A,55,1.5,Rare 129 | 128,Tauros,Wild Bull Pokémon,Normal,N/A,88.4,1.4,Epic 130 | 129,Magikarp,Fish Pokémon,Water,N/A,10,0.9,Very Common 131 | 130,Gyarados,Atrocious Pokémon,Water,Flying,235,6.5,Very Rare 132 | 131,Lapras,Transport Pokémon,Water,Ice,220,2.5,Very Rare 133 | 132,Ditto,Transform Pokémon,Normal,N/A,4,0.3,Legendary 134 | 133,Eevee,Evolution Pokémon,Normal,N/A,6.5,0.3,Common 135 | 134,Vaporeon,Bubble Jet Pokémon,Water,N/A,29,1,Very Rare 136 | 135,Jolteon,Lightning Pokémon,Electric,N/A,24.5,0.8,Very Rare 137 | 136,Flareon,Flame Pokémon,Fire,N/A,25,0.9,Very Rare 138 | 137,Porygon,Virtual Pokémon,Normal,N/A,36.5,0.8,Special 139 | 138,Omanyte,Spiral Pokémon,Rock,Water,7.5,0.4,Special 140 | 139,Omastar,Spiral Pokémon,Rock,Water,35,1,Epic 141 | 140,Kabuto,Shellfish Pokémon,Rock,Water,11.5,0.5,Uncommon 142 | 141,Kabutops,Shellfish Pokémon,Rock,Water,40.5,1.3,Very Rare 143 | 142,Aerodactyl,Fossil Pokémon,Rock,Flying,59,1.8,Special 144 | 143,Snorlax,Sleeping Pokémon,Normal,N/A,460,2.1,Rare 145 | 144,Articuno,Freeze Pokémon,Ice,Flying,55.4,1.7,Legendary 146 | 145,Zapdos,Electric Pokémon,Electric,Flying,52.6,1.6,Legendary 147 | 146,Moltres,Flame Pokémon,Fire,Flying,60,2,Legendary 148 | 147,Dratini,Dragon Pokémon,Dragon,N/A,3.3,1.8,Uncommon 149 | 148,Dragonair,Dragon Pokémon,Dragon,N/A,16.5,4,Very Rare 150 | 149,Dragonite,Dragon Pokémon,Dragon,Flying,210,2.2,Epic 151 | 150,Mewtwo,Genetic Pokémon,Psychic,N/A,122,2,Legendary 152 | 151,Mew,New Species Pokémon,Psychic,N/A,4,0.4,Legendary 153 | -------------------------------------------------------------------------------- /language_patches/deutsch_german.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE pokemon_info ADD name_de text; 2 | UPDATE pokemon_info SET name_de='Bisasam' WHERE pokemon_id=1; 3 | UPDATE pokemon_info SET name_de='Bisaknosp' WHERE pokemon_id=2; 4 | UPDATE pokemon_info SET name_de='Bisaflor' WHERE pokemon_id=3; 5 | UPDATE pokemon_info SET name_de='Glumanda' WHERE pokemon_id=4; 6 | UPDATE pokemon_info SET name_de='Glutexo' WHERE pokemon_id=5; 7 | UPDATE pokemon_info SET name_de='Glurak' WHERE pokemon_id=6; 8 | UPDATE pokemon_info SET name_de='Schiggy' WHERE pokemon_id=7; 9 | UPDATE pokemon_info SET name_de='Schillok' WHERE pokemon_id=8; 10 | UPDATE pokemon_info SET name_de='Turtok' WHERE pokemon_id=9; 11 | UPDATE pokemon_info SET name_de='Raupy' WHERE pokemon_id=10; 12 | UPDATE pokemon_info SET name_de='Safcon' WHERE pokemon_id=11; 13 | UPDATE pokemon_info SET name_de='Smettbo' WHERE pokemon_id=12; 14 | UPDATE pokemon_info SET name_de='Hornliu' WHERE pokemon_id=13; 15 | UPDATE pokemon_info SET name_de='Kokuna' WHERE pokemon_id=14; 16 | UPDATE pokemon_info SET name_de='Bibor' WHERE pokemon_id=15; 17 | UPDATE pokemon_info SET name_de='Taubsi' WHERE pokemon_id=16; 18 | UPDATE pokemon_info SET name_de='Tauboga' WHERE pokemon_id=17; 19 | UPDATE pokemon_info SET name_de='Tauboss' WHERE pokemon_id=18; 20 | UPDATE pokemon_info SET name_de='Rattfratz' WHERE pokemon_id=19; 21 | UPDATE pokemon_info SET name_de='Rattikarl' WHERE pokemon_id=20; 22 | UPDATE pokemon_info SET name_de='Habitak' WHERE pokemon_id=21; 23 | UPDATE pokemon_info SET name_de='Ibitak' WHERE pokemon_id=22; 24 | UPDATE pokemon_info SET name_de='Rettan' WHERE pokemon_id=23; 25 | UPDATE pokemon_info SET name_de='Arbok' WHERE pokemon_id=24; 26 | UPDATE pokemon_info SET name_de='Pikachu' WHERE pokemon_id=25; 27 | UPDATE pokemon_info SET name_de='Raichu' WHERE pokemon_id=26; 28 | UPDATE pokemon_info SET name_de='Sandan' WHERE pokemon_id=27; 29 | UPDATE pokemon_info SET name_de='Sandamer' WHERE pokemon_id=28; 30 | UPDATE pokemon_info SET name_de='Nidoran♀' WHERE pokemon_id=29; 31 | UPDATE pokemon_info SET name_de='Nidorina' WHERE pokemon_id=30; 32 | UPDATE pokemon_info SET name_de='Nidoqueen' WHERE pokemon_id=31; 33 | UPDATE pokemon_info SET name_de='Nidoran♂' WHERE pokemon_id=32; 34 | UPDATE pokemon_info SET name_de='Nidorino' WHERE pokemon_id=33; 35 | UPDATE pokemon_info SET name_de='Nidoking' WHERE pokemon_id=34; 36 | UPDATE pokemon_info SET name_de='Piepi' WHERE pokemon_id=35; 37 | UPDATE pokemon_info SET name_de='Pixi' WHERE pokemon_id=36; 38 | UPDATE pokemon_info SET name_de='Vulpix' WHERE pokemon_id=37; 39 | UPDATE pokemon_info SET name_de='Vulnona' WHERE pokemon_id=38; 40 | UPDATE pokemon_info SET name_de='Pummeluff' WHERE pokemon_id=39; 41 | UPDATE pokemon_info SET name_de='Knuddeluff' WHERE pokemon_id=40; 42 | UPDATE pokemon_info SET name_de='Zubat' WHERE pokemon_id=41; 43 | UPDATE pokemon_info SET name_de='Golbat' WHERE pokemon_id=42; 44 | UPDATE pokemon_info SET name_de='Myrapla' WHERE pokemon_id=43; 45 | UPDATE pokemon_info SET name_de='Duflor' WHERE pokemon_id=44; 46 | UPDATE pokemon_info SET name_de='Giflor' WHERE pokemon_id=45; 47 | UPDATE pokemon_info SET name_de='Paras' WHERE pokemon_id=46; 48 | UPDATE pokemon_info SET name_de='Parasek' WHERE pokemon_id=47; 49 | UPDATE pokemon_info SET name_de='Bluzuk' WHERE pokemon_id=48; 50 | UPDATE pokemon_info SET name_de='Omot' WHERE pokemon_id=49; 51 | UPDATE pokemon_info SET name_de='Digda' WHERE pokemon_id=50; 52 | UPDATE pokemon_info SET name_de='Digdri' WHERE pokemon_id=51; 53 | UPDATE pokemon_info SET name_de='Mauzi' WHERE pokemon_id=52; 54 | UPDATE pokemon_info SET name_de='Snobilikat' WHERE pokemon_id=53; 55 | UPDATE pokemon_info SET name_de='Enton' WHERE pokemon_id=54; 56 | UPDATE pokemon_info SET name_de='Entoron' WHERE pokemon_id=55; 57 | UPDATE pokemon_info SET name_de='Menki' WHERE pokemon_id=56; 58 | UPDATE pokemon_info SET name_de='Rasaff' WHERE pokemon_id=57; 59 | UPDATE pokemon_info SET name_de='Fukano' WHERE pokemon_id=58; 60 | UPDATE pokemon_info SET name_de='Arkani' WHERE pokemon_id=59; 61 | UPDATE pokemon_info SET name_de='Quapsel' WHERE pokemon_id=60; 62 | UPDATE pokemon_info SET name_de='Quaputzi' WHERE pokemon_id=61; 63 | UPDATE pokemon_info SET name_de='Quappo' WHERE pokemon_id=62; 64 | UPDATE pokemon_info SET name_de='Abra' WHERE pokemon_id=63; 65 | UPDATE pokemon_info SET name_de='Kadabra' WHERE pokemon_id=64; 66 | UPDATE pokemon_info SET name_de='Simsala' WHERE pokemon_id=65; 67 | UPDATE pokemon_info SET name_de='Machollo' WHERE pokemon_id=66; 68 | UPDATE pokemon_info SET name_de='Maschock' WHERE pokemon_id=67; 69 | UPDATE pokemon_info SET name_de='Machomei' WHERE pokemon_id=68; 70 | UPDATE pokemon_info SET name_de='Knofensa' WHERE pokemon_id=69; 71 | UPDATE pokemon_info SET name_de='Ultrigaria' WHERE pokemon_id=70; 72 | UPDATE pokemon_info SET name_de='Sarzenia' WHERE pokemon_id=71; 73 | UPDATE pokemon_info SET name_de='Tentacha' WHERE pokemon_id=72; 74 | UPDATE pokemon_info SET name_de='Tentoxa' WHERE pokemon_id=73; 75 | UPDATE pokemon_info SET name_de='Kleinstein' WHERE pokemon_id=74; 76 | UPDATE pokemon_info SET name_de='Georok' WHERE pokemon_id=75; 77 | UPDATE pokemon_info SET name_de='Geowaz' WHERE pokemon_id=76; 78 | UPDATE pokemon_info SET name_de='Ponita' WHERE pokemon_id=77; 79 | UPDATE pokemon_info SET name_de='Gallopa' WHERE pokemon_id=78; 80 | UPDATE pokemon_info SET name_de='Flegmon' WHERE pokemon_id=79; 81 | UPDATE pokemon_info SET name_de='Lahmus' WHERE pokemon_id=80; 82 | UPDATE pokemon_info SET name_de='Magnetilo' WHERE pokemon_id=81; 83 | UPDATE pokemon_info SET name_de='Magneton' WHERE pokemon_id=82; 84 | UPDATE pokemon_info SET name_de='Porenta' WHERE pokemon_id=83; 85 | UPDATE pokemon_info SET name_de='Dodu' WHERE pokemon_id=84; 86 | UPDATE pokemon_info SET name_de='Dodri' WHERE pokemon_id=85; 87 | UPDATE pokemon_info SET name_de='Jurob' WHERE pokemon_id=86; 88 | UPDATE pokemon_info SET name_de='Jugong' WHERE pokemon_id=87; 89 | UPDATE pokemon_info SET name_de='Sleima' WHERE pokemon_id=88; 90 | UPDATE pokemon_info SET name_de='Sleimok' WHERE pokemon_id=89; 91 | UPDATE pokemon_info SET name_de='Muschas' WHERE pokemon_id=90; 92 | UPDATE pokemon_info SET name_de='Austos' WHERE pokemon_id=91; 93 | UPDATE pokemon_info SET name_de='Nebulak' WHERE pokemon_id=92; 94 | UPDATE pokemon_info SET name_de='Alpollo' WHERE pokemon_id=93; 95 | UPDATE pokemon_info SET name_de='Gengar' WHERE pokemon_id=94; 96 | UPDATE pokemon_info SET name_de='Onix' WHERE pokemon_id=95; 97 | UPDATE pokemon_info SET name_de='Traumato' WHERE pokemon_id=96; 98 | UPDATE pokemon_info SET name_de='Hypno' WHERE pokemon_id=97; 99 | UPDATE pokemon_info SET name_de='Krabby' WHERE pokemon_id=98; 100 | UPDATE pokemon_info SET name_de='Kingler' WHERE pokemon_id=99; 101 | UPDATE pokemon_info SET name_de='Voltobal' WHERE pokemon_id=100; 102 | UPDATE pokemon_info SET name_de='Lektrobal' WHERE pokemon_id=101; 103 | UPDATE pokemon_info SET name_de='Owei' WHERE pokemon_id=102; 104 | UPDATE pokemon_info SET name_de='Kokowei' WHERE pokemon_id=103; 105 | UPDATE pokemon_info SET name_de='Tragosso' WHERE pokemon_id=104; 106 | UPDATE pokemon_info SET name_de='Knogga' WHERE pokemon_id=105; 107 | UPDATE pokemon_info SET name_de='Kicklee' WHERE pokemon_id=106; 108 | UPDATE pokemon_info SET name_de='Nockchan' WHERE pokemon_id=107; 109 | UPDATE pokemon_info SET name_de='Schlurp' WHERE pokemon_id=108; 110 | UPDATE pokemon_info SET name_de='Smogon' WHERE pokemon_id=109; 111 | UPDATE pokemon_info SET name_de='Smogmog' WHERE pokemon_id=110; 112 | UPDATE pokemon_info SET name_de='Rihorn' WHERE pokemon_id=111; 113 | UPDATE pokemon_info SET name_de='Rizeros' WHERE pokemon_id=112; 114 | UPDATE pokemon_info SET name_de='Chaneira' WHERE pokemon_id=113; 115 | UPDATE pokemon_info SET name_de='Tangela' WHERE pokemon_id=114; 116 | UPDATE pokemon_info SET name_de='Kangama' WHERE pokemon_id=115; 117 | UPDATE pokemon_info SET name_de='Seeper' WHERE pokemon_id=116; 118 | UPDATE pokemon_info SET name_de='Seemon' WHERE pokemon_id=117; 119 | UPDATE pokemon_info SET name_de='Goldini' WHERE pokemon_id=118; 120 | UPDATE pokemon_info SET name_de='Golking' WHERE pokemon_id=119; 121 | UPDATE pokemon_info SET name_de='Sterndu' WHERE pokemon_id=120; 122 | UPDATE pokemon_info SET name_de='Starmie' WHERE pokemon_id=121; 123 | UPDATE pokemon_info SET name_de='Pantimos' WHERE pokemon_id=122; 124 | UPDATE pokemon_info SET name_de='Sichlor' WHERE pokemon_id=123; 125 | UPDATE pokemon_info SET name_de='Rossana' WHERE pokemon_id=124; 126 | UPDATE pokemon_info SET name_de='Elektek' WHERE pokemon_id=125; 127 | UPDATE pokemon_info SET name_de='Magmar' WHERE pokemon_id=126; 128 | UPDATE pokemon_info SET name_de='Pinsir' WHERE pokemon_id=127; 129 | UPDATE pokemon_info SET name_de='Tauros' WHERE pokemon_id=128; 130 | UPDATE pokemon_info SET name_de='Karpador' WHERE pokemon_id=129; 131 | UPDATE pokemon_info SET name_de='Garados' WHERE pokemon_id=130; 132 | UPDATE pokemon_info SET name_de='Lapras' WHERE pokemon_id=131; 133 | UPDATE pokemon_info SET name_de='Ditto' WHERE pokemon_id=132; 134 | UPDATE pokemon_info SET name_de='Evoli' WHERE pokemon_id=133; 135 | UPDATE pokemon_info SET name_de='Aquana' WHERE pokemon_id=134; 136 | UPDATE pokemon_info SET name_de='Blitza' WHERE pokemon_id=135; 137 | UPDATE pokemon_info SET name_de='Flamara' WHERE pokemon_id=136; 138 | UPDATE pokemon_info SET name_de='Porygon' WHERE pokemon_id=137; 139 | UPDATE pokemon_info SET name_de='Amonitas' WHERE pokemon_id=138; 140 | UPDATE pokemon_info SET name_de='Amoroso' WHERE pokemon_id=139; 141 | UPDATE pokemon_info SET name_de='Kabuto' WHERE pokemon_id=140; 142 | UPDATE pokemon_info SET name_de='Kabutops' WHERE pokemon_id=141; 143 | UPDATE pokemon_info SET name_de='Aerodactyl' WHERE pokemon_id=142; 144 | UPDATE pokemon_info SET name_de='Relaxo' WHERE pokemon_id=143; 145 | UPDATE pokemon_info SET name_de='Arktos' WHERE pokemon_id=144; 146 | UPDATE pokemon_info SET name_de='Zapdos' WHERE pokemon_id=145; 147 | UPDATE pokemon_info SET name_de='Lavados' WHERE pokemon_id=146; 148 | UPDATE pokemon_info SET name_de='Dratini' WHERE pokemon_id=147; 149 | UPDATE pokemon_info SET name_de='Dragonir' WHERE pokemon_id=148; 150 | UPDATE pokemon_info SET name_de='Dragoran' WHERE pokemon_id=149; 151 | UPDATE pokemon_info SET name_de='Mewtu' WHERE pokemon_id=150; 152 | UPDATE pokemon_info SET name_de='Mew' WHERE pokemon_id=151; 153 | -------------------------------------------------------------------------------- /language_patches/français_french.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE pokemon_info ADD name_fr text; 2 | UPDATE pokemon_info SET name_fr='Bulbizarre' WHERE pokemon_id=1; 3 | UPDATE pokemon_info SET name_fr='Herbizarre' WHERE pokemon_id=2; 4 | UPDATE pokemon_info SET name_fr='Florizarre' WHERE pokemon_id=3; 5 | UPDATE pokemon_info SET name_fr='Salamèche' WHERE pokemon_id=4; 6 | UPDATE pokemon_info SET name_fr='Reptincel' WHERE pokemon_id=5; 7 | UPDATE pokemon_info SET name_fr='Dracaufeu' WHERE pokemon_id=6; 8 | UPDATE pokemon_info SET name_fr='Carapuce' WHERE pokemon_id=7; 9 | UPDATE pokemon_info SET name_fr='Carabaffe' WHERE pokemon_id=8; 10 | UPDATE pokemon_info SET name_fr='Tortank' WHERE pokemon_id=9; 11 | UPDATE pokemon_info SET name_fr='Chenipan' WHERE pokemon_id=10; 12 | UPDATE pokemon_info SET name_fr='Chrysacier' WHERE pokemon_id=11; 13 | UPDATE pokemon_info SET name_fr='Papilusion' WHERE pokemon_id=12; 14 | UPDATE pokemon_info SET name_fr='Aspicot' WHERE pokemon_id=13; 15 | UPDATE pokemon_info SET name_fr='Coconfort' WHERE pokemon_id=14; 16 | UPDATE pokemon_info SET name_fr='Dardargnan' WHERE pokemon_id=15; 17 | UPDATE pokemon_info SET name_fr='Roucool' WHERE pokemon_id=16; 18 | UPDATE pokemon_info SET name_fr='Roucoups' WHERE pokemon_id=17; 19 | UPDATE pokemon_info SET name_fr='Roucarnage' WHERE pokemon_id=18; 20 | UPDATE pokemon_info SET name_fr='Rattata' WHERE pokemon_id=19; 21 | UPDATE pokemon_info SET name_fr='Rattatac' WHERE pokemon_id=20; 22 | UPDATE pokemon_info SET name_fr='Piafabec' WHERE pokemon_id=21; 23 | UPDATE pokemon_info SET name_fr='Rapasdepic' WHERE pokemon_id=22; 24 | UPDATE pokemon_info SET name_fr='Abo' WHERE pokemon_id=23; 25 | UPDATE pokemon_info SET name_fr='Arbok' WHERE pokemon_id=24; 26 | UPDATE pokemon_info SET name_fr='Pikachu' WHERE pokemon_id=25; 27 | UPDATE pokemon_info SET name_fr='Raichu' WHERE pokemon_id=26; 28 | UPDATE pokemon_info SET name_fr='Sabelette' WHERE pokemon_id=27; 29 | UPDATE pokemon_info SET name_fr='Sablaireau' WHERE pokemon_id=28; 30 | UPDATE pokemon_info SET name_fr='Nidoran♀' WHERE pokemon_id=29; 31 | UPDATE pokemon_info SET name_fr='Nidorina' WHERE pokemon_id=30; 32 | UPDATE pokemon_info SET name_fr='Nidoqueen' WHERE pokemon_id=31; 33 | UPDATE pokemon_info SET name_fr='Nidoran♂' WHERE pokemon_id=32; 34 | UPDATE pokemon_info SET name_fr='Nidorino' WHERE pokemon_id=33; 35 | UPDATE pokemon_info SET name_fr='Nidoking' WHERE pokemon_id=34; 36 | UPDATE pokemon_info SET name_fr='Mélofée' WHERE pokemon_id=35; 37 | UPDATE pokemon_info SET name_fr='Mélodelfe' WHERE pokemon_id=36; 38 | UPDATE pokemon_info SET name_fr='Goupix' WHERE pokemon_id=37; 39 | UPDATE pokemon_info SET name_fr='Feunard' WHERE pokemon_id=38; 40 | UPDATE pokemon_info SET name_fr='Rondoudou' WHERE pokemon_id=39; 41 | UPDATE pokemon_info SET name_fr='Grodoudou' WHERE pokemon_id=40; 42 | UPDATE pokemon_info SET name_fr='Nosferapti' WHERE pokemon_id=41; 43 | UPDATE pokemon_info SET name_fr='Nosferalto' WHERE pokemon_id=42; 44 | UPDATE pokemon_info SET name_fr='Mystherbe' WHERE pokemon_id=43; 45 | UPDATE pokemon_info SET name_fr='Ortide' WHERE pokemon_id=44; 46 | UPDATE pokemon_info SET name_fr='Rafflesia' WHERE pokemon_id=45; 47 | UPDATE pokemon_info SET name_fr='Paras' WHERE pokemon_id=46; 48 | UPDATE pokemon_info SET name_fr='Parasect' WHERE pokemon_id=47; 49 | UPDATE pokemon_info SET name_fr='Mimitoss' WHERE pokemon_id=48; 50 | UPDATE pokemon_info SET name_fr='Aéromite' WHERE pokemon_id=49; 51 | UPDATE pokemon_info SET name_fr='Taupiqueur' WHERE pokemon_id=50; 52 | UPDATE pokemon_info SET name_fr='Triopikeur' WHERE pokemon_id=51; 53 | UPDATE pokemon_info SET name_fr='Miaouss' WHERE pokemon_id=52; 54 | UPDATE pokemon_info SET name_fr='Persian' WHERE pokemon_id=53; 55 | UPDATE pokemon_info SET name_fr='Psykokwak' WHERE pokemon_id=54; 56 | UPDATE pokemon_info SET name_fr='Akwakwak' WHERE pokemon_id=55; 57 | UPDATE pokemon_info SET name_fr='Férosinge' WHERE pokemon_id=56; 58 | UPDATE pokemon_info SET name_fr='Colossinge' WHERE pokemon_id=57; 59 | UPDATE pokemon_info SET name_fr='Caninos' WHERE pokemon_id=58; 60 | UPDATE pokemon_info SET name_fr='Arcanin' WHERE pokemon_id=59; 61 | UPDATE pokemon_info SET name_fr='Ptitard' WHERE pokemon_id=60; 62 | UPDATE pokemon_info SET name_fr='Têtarte' WHERE pokemon_id=61; 63 | UPDATE pokemon_info SET name_fr='Tartard' WHERE pokemon_id=62; 64 | UPDATE pokemon_info SET name_fr='Abra' WHERE pokemon_id=63; 65 | UPDATE pokemon_info SET name_fr='Kadabra' WHERE pokemon_id=64; 66 | UPDATE pokemon_info SET name_fr='Alakazam' WHERE pokemon_id=65; 67 | UPDATE pokemon_info SET name_fr='Machoc' WHERE pokemon_id=66; 68 | UPDATE pokemon_info SET name_fr='Machopeur' WHERE pokemon_id=67; 69 | UPDATE pokemon_info SET name_fr='Mackogneur' WHERE pokemon_id=68; 70 | UPDATE pokemon_info SET name_fr='Chétiflor' WHERE pokemon_id=69; 71 | UPDATE pokemon_info SET name_fr='Boustiflor' WHERE pokemon_id=70; 72 | UPDATE pokemon_info SET name_fr='Empiflor' WHERE pokemon_id=71; 73 | UPDATE pokemon_info SET name_fr='Tentacool' WHERE pokemon_id=72; 74 | UPDATE pokemon_info SET name_fr='Tentacruel' WHERE pokemon_id=73; 75 | UPDATE pokemon_info SET name_fr='Racaillou' WHERE pokemon_id=74; 76 | UPDATE pokemon_info SET name_fr='Gravalanch' WHERE pokemon_id=75; 77 | UPDATE pokemon_info SET name_fr='Grolem' WHERE pokemon_id=76; 78 | UPDATE pokemon_info SET name_fr='Ponyta' WHERE pokemon_id=77; 79 | UPDATE pokemon_info SET name_fr='Galopa' WHERE pokemon_id=78; 80 | UPDATE pokemon_info SET name_fr='Ramoloss' WHERE pokemon_id=79; 81 | UPDATE pokemon_info SET name_fr='Flagadoss' WHERE pokemon_id=80; 82 | UPDATE pokemon_info SET name_fr='Magnéti' WHERE pokemon_id=81; 83 | UPDATE pokemon_info SET name_fr='Magnéton' WHERE pokemon_id=82; 84 | UPDATE pokemon_info SET name_fr='Canarticho' WHERE pokemon_id=83; 85 | UPDATE pokemon_info SET name_fr='Doduo' WHERE pokemon_id=84; 86 | UPDATE pokemon_info SET name_fr='Dodrio' WHERE pokemon_id=85; 87 | UPDATE pokemon_info SET name_fr='Otaria' WHERE pokemon_id=86; 88 | UPDATE pokemon_info SET name_fr='Lamantine' WHERE pokemon_id=87; 89 | UPDATE pokemon_info SET name_fr='Tadmorv' WHERE pokemon_id=88; 90 | UPDATE pokemon_info SET name_fr='Grotadmorv' WHERE pokemon_id=89; 91 | UPDATE pokemon_info SET name_fr='Kokiyas' WHERE pokemon_id=90; 92 | UPDATE pokemon_info SET name_fr='Crustabri' WHERE pokemon_id=91; 93 | UPDATE pokemon_info SET name_fr='Fantominus' WHERE pokemon_id=92; 94 | UPDATE pokemon_info SET name_fr='Spectrum' WHERE pokemon_id=93; 95 | UPDATE pokemon_info SET name_fr='Ectoplasma' WHERE pokemon_id=94; 96 | UPDATE pokemon_info SET name_fr='Onix' WHERE pokemon_id=95; 97 | UPDATE pokemon_info SET name_fr='Soporifik' WHERE pokemon_id=96; 98 | UPDATE pokemon_info SET name_fr='Hypnomade' WHERE pokemon_id=97; 99 | UPDATE pokemon_info SET name_fr='Krabby' WHERE pokemon_id=98; 100 | UPDATE pokemon_info SET name_fr='Krabboss' WHERE pokemon_id=99; 101 | UPDATE pokemon_info SET name_fr='Voltorbe' WHERE pokemon_id=100; 102 | UPDATE pokemon_info SET name_fr='Électrode' WHERE pokemon_id=101; 103 | UPDATE pokemon_info SET name_fr='Nœunœuf' WHERE pokemon_id=102; 104 | UPDATE pokemon_info SET name_fr='Noadkoko' WHERE pokemon_id=103; 105 | UPDATE pokemon_info SET name_fr='Osselait' WHERE pokemon_id=104; 106 | UPDATE pokemon_info SET name_fr='Ossatueur' WHERE pokemon_id=105; 107 | UPDATE pokemon_info SET name_fr='Kicklee' WHERE pokemon_id=106; 108 | UPDATE pokemon_info SET name_fr='Tygnon' WHERE pokemon_id=107; 109 | UPDATE pokemon_info SET name_fr='Excelangue' WHERE pokemon_id=108; 110 | UPDATE pokemon_info SET name_fr='Smogo' WHERE pokemon_id=109; 111 | UPDATE pokemon_info SET name_fr='Smogogo' WHERE pokemon_id=110; 112 | UPDATE pokemon_info SET name_fr='Rhinocorne' WHERE pokemon_id=111; 113 | UPDATE pokemon_info SET name_fr='Rhinoféros' WHERE pokemon_id=112; 114 | UPDATE pokemon_info SET name_fr='Leveinard' WHERE pokemon_id=113; 115 | UPDATE pokemon_info SET name_fr='Saquedeneu' WHERE pokemon_id=114; 116 | UPDATE pokemon_info SET name_fr='Kangourex' WHERE pokemon_id=115; 117 | UPDATE pokemon_info SET name_fr='Hypotrempe' WHERE pokemon_id=116; 118 | UPDATE pokemon_info SET name_fr='Hypocéan' WHERE pokemon_id=117; 119 | UPDATE pokemon_info SET name_fr='Poissirène' WHERE pokemon_id=118; 120 | UPDATE pokemon_info SET name_fr='Poissoroy' WHERE pokemon_id=119; 121 | UPDATE pokemon_info SET name_fr='Stari' WHERE pokemon_id=120; 122 | UPDATE pokemon_info SET name_fr='Staross' WHERE pokemon_id=121; 123 | UPDATE pokemon_info SET name_fr='M.Mime' WHERE pokemon_id=122; 124 | UPDATE pokemon_info SET name_fr='Insécateur' WHERE pokemon_id=123; 125 | UPDATE pokemon_info SET name_fr='Lippoutou' WHERE pokemon_id=124; 126 | UPDATE pokemon_info SET name_fr='Élektek' WHERE pokemon_id=125; 127 | UPDATE pokemon_info SET name_fr='Magmar' WHERE pokemon_id=126; 128 | UPDATE pokemon_info SET name_fr='Scarabrute' WHERE pokemon_id=127; 129 | UPDATE pokemon_info SET name_fr='Tauros' WHERE pokemon_id=128; 130 | UPDATE pokemon_info SET name_fr='Magicarpe' WHERE pokemon_id=129; 131 | UPDATE pokemon_info SET name_fr='Léviator' WHERE pokemon_id=130; 132 | UPDATE pokemon_info SET name_fr='Lokhlass' WHERE pokemon_id=131; 133 | UPDATE pokemon_info SET name_fr='Métamorph' WHERE pokemon_id=132; 134 | UPDATE pokemon_info SET name_fr='Évoli' WHERE pokemon_id=133; 135 | UPDATE pokemon_info SET name_fr='Aquali' WHERE pokemon_id=134; 136 | UPDATE pokemon_info SET name_fr='Voltali' WHERE pokemon_id=135; 137 | UPDATE pokemon_info SET name_fr='Pyroli' WHERE pokemon_id=136; 138 | UPDATE pokemon_info SET name_fr='Porygon' WHERE pokemon_id=137; 139 | UPDATE pokemon_info SET name_fr='Amonita' WHERE pokemon_id=138; 140 | UPDATE pokemon_info SET name_fr='Amonistar' WHERE pokemon_id=139; 141 | UPDATE pokemon_info SET name_fr='Kabuto' WHERE pokemon_id=140; 142 | UPDATE pokemon_info SET name_fr='Kabutops' WHERE pokemon_id=141; 143 | UPDATE pokemon_info SET name_fr='Ptéra' WHERE pokemon_id=142; 144 | UPDATE pokemon_info SET name_fr='Ronflex' WHERE pokemon_id=143; 145 | UPDATE pokemon_info SET name_fr='Artikodin' WHERE pokemon_id=144; 146 | UPDATE pokemon_info SET name_fr='Électhor' WHERE pokemon_id=145; 147 | UPDATE pokemon_info SET name_fr='Sulfura' WHERE pokemon_id=146; 148 | UPDATE pokemon_info SET name_fr='Minidraco' WHERE pokemon_id=147; 149 | UPDATE pokemon_info SET name_fr='Draco' WHERE pokemon_id=148; 150 | UPDATE pokemon_info SET name_fr='Dracolosse' WHERE pokemon_id=149; 151 | UPDATE pokemon_info SET name_fr='Mewtwo' WHERE pokemon_id=150; 152 | UPDATE pokemon_info SET name_fr='Mew' WHERE pokemon_id=151; 153 | -------------------------------------------------------------------------------- /language_patches/русский_russian.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE pokemon_info ADD name_ru text; 2 | UPDATE pokemon_info SET name_ru='Бульбазавр' WHERE pokemon_id=1; 3 | UPDATE pokemon_info SET name_ru='Айвизавр' WHERE pokemon_id=2; 4 | UPDATE pokemon_info SET name_ru='Венузавр' WHERE pokemon_id=3; 5 | UPDATE pokemon_info SET name_ru='Чармандер' WHERE pokemon_id=4; 6 | UPDATE pokemon_info SET name_ru='Чармелеон' WHERE pokemon_id=5; 7 | UPDATE pokemon_info SET name_ru='Чаризард' WHERE pokemon_id=6; 8 | UPDATE pokemon_info SET name_ru='Сквиртл' WHERE pokemon_id=7; 9 | UPDATE pokemon_info SET name_ru='Вартортл' WHERE pokemon_id=8; 10 | UPDATE pokemon_info SET name_ru='Бластойз' WHERE pokemon_id=9; 11 | UPDATE pokemon_info SET name_ru='Катерпи' WHERE pokemon_id=10; 12 | UPDATE pokemon_info SET name_ru='Метапод' WHERE pokemon_id=11; 13 | UPDATE pokemon_info SET name_ru='Баттерфри' WHERE pokemon_id=12; 14 | UPDATE pokemon_info SET name_ru='Видл' WHERE pokemon_id=13; 15 | UPDATE pokemon_info SET name_ru='Какуна' WHERE pokemon_id=14; 16 | UPDATE pokemon_info SET name_ru='Бидрилл' WHERE pokemon_id=15; 17 | UPDATE pokemon_info SET name_ru='Пиджи' WHERE pokemon_id=16; 18 | UPDATE pokemon_info SET name_ru='Пиджеотто' WHERE pokemon_id=17; 19 | UPDATE pokemon_info SET name_ru='Пиджеот' WHERE pokemon_id=18; 20 | UPDATE pokemon_info SET name_ru='Раттата' WHERE pokemon_id=19; 21 | UPDATE pokemon_info SET name_ru='Ратикейт' WHERE pokemon_id=20; 22 | UPDATE pokemon_info SET name_ru='Спироу' WHERE pokemon_id=21; 23 | UPDATE pokemon_info SET name_ru='Фироу' WHERE pokemon_id=22; 24 | UPDATE pokemon_info SET name_ru='Эканс' WHERE pokemon_id=23; 25 | UPDATE pokemon_info SET name_ru='Арбок' WHERE pokemon_id=24; 26 | UPDATE pokemon_info SET name_ru='Пикачу' WHERE pokemon_id=25; 27 | UPDATE pokemon_info SET name_ru='Райчу' WHERE pokemon_id=26; 28 | UPDATE pokemon_info SET name_ru='Сэндшрю' WHERE pokemon_id=27; 29 | UPDATE pokemon_info SET name_ru='Сэндслэш' WHERE pokemon_id=28; 30 | UPDATE pokemon_info SET name_ru='Нидоран♀' WHERE pokemon_id=29; 31 | UPDATE pokemon_info SET name_ru='Нидорина' WHERE pokemon_id=30; 32 | UPDATE pokemon_info SET name_ru='Нидоквин' WHERE pokemon_id=31; 33 | UPDATE pokemon_info SET name_ru='Нидоран♂' WHERE pokemon_id=32; 34 | UPDATE pokemon_info SET name_ru='Нидорино' WHERE pokemon_id=33; 35 | UPDATE pokemon_info SET name_ru='Нидокинг' WHERE pokemon_id=34; 36 | UPDATE pokemon_info SET name_ru='Клефэйри' WHERE pokemon_id=35; 37 | UPDATE pokemon_info SET name_ru='Клефейбл' WHERE pokemon_id=36; 38 | UPDATE pokemon_info SET name_ru='Валпикс' WHERE pokemon_id=37; 39 | UPDATE pokemon_info SET name_ru='Найнтэйлс' WHERE pokemon_id=38; 40 | UPDATE pokemon_info SET name_ru='Джигглипафф' WHERE pokemon_id=39; 41 | UPDATE pokemon_info SET name_ru='Вигглитафф' WHERE pokemon_id=40; 42 | UPDATE pokemon_info SET name_ru='Зубат' WHERE pokemon_id=41; 43 | UPDATE pokemon_info SET name_ru='Голбат' WHERE pokemon_id=42; 44 | UPDATE pokemon_info SET name_ru='Оддиш' WHERE pokemon_id=43; 45 | UPDATE pokemon_info SET name_ru='Глум' WHERE pokemon_id=44; 46 | UPDATE pokemon_info SET name_ru='Вайлплюм' WHERE pokemon_id=45; 47 | UPDATE pokemon_info SET name_ru='Парас' WHERE pokemon_id=46; 48 | UPDATE pokemon_info SET name_ru='Парасект' WHERE pokemon_id=47; 49 | UPDATE pokemon_info SET name_ru='Венонат' WHERE pokemon_id=48; 50 | UPDATE pokemon_info SET name_ru='Веномот' WHERE pokemon_id=49; 51 | UPDATE pokemon_info SET name_ru='Диглетт' WHERE pokemon_id=50; 52 | UPDATE pokemon_info SET name_ru='Дагтрио' WHERE pokemon_id=51; 53 | UPDATE pokemon_info SET name_ru='Мяут' WHERE pokemon_id=52; 54 | UPDATE pokemon_info SET name_ru='Персиан' WHERE pokemon_id=53; 55 | UPDATE pokemon_info SET name_ru='Псайдак' WHERE pokemon_id=54; 56 | UPDATE pokemon_info SET name_ru='Голдак' WHERE pokemon_id=55; 57 | UPDATE pokemon_info SET name_ru='Манки' WHERE pokemon_id=56; 58 | UPDATE pokemon_info SET name_ru='Праймейп' WHERE pokemon_id=57; 59 | UPDATE pokemon_info SET name_ru='Гроулит' WHERE pokemon_id=58; 60 | UPDATE pokemon_info SET name_ru='Арканайн' WHERE pokemon_id=59; 61 | UPDATE pokemon_info SET name_ru='Поливаг' WHERE pokemon_id=60; 62 | UPDATE pokemon_info SET name_ru='Поливирл' WHERE pokemon_id=61; 63 | UPDATE pokemon_info SET name_ru='Поливрат' WHERE pokemon_id=62; 64 | UPDATE pokemon_info SET name_ru='Абра' WHERE pokemon_id=63; 65 | UPDATE pokemon_info SET name_ru='Кадабра' WHERE pokemon_id=64; 66 | UPDATE pokemon_info SET name_ru='Алаказам' WHERE pokemon_id=65; 67 | UPDATE pokemon_info SET name_ru='Мачоп' WHERE pokemon_id=66; 68 | UPDATE pokemon_info SET name_ru='Мачоук' WHERE pokemon_id=67; 69 | UPDATE pokemon_info SET name_ru='Мачамп' WHERE pokemon_id=68; 70 | UPDATE pokemon_info SET name_ru='Беллспраут' WHERE pokemon_id=69; 71 | UPDATE pokemon_info SET name_ru='Випинбелл' WHERE pokemon_id=70; 72 | UPDATE pokemon_info SET name_ru='Виктрибел' WHERE pokemon_id=71; 73 | UPDATE pokemon_info SET name_ru='Тентакул' WHERE pokemon_id=72; 74 | UPDATE pokemon_info SET name_ru='Тентакрул' WHERE pokemon_id=73; 75 | UPDATE pokemon_info SET name_ru='Геодуд' WHERE pokemon_id=74; 76 | UPDATE pokemon_info SET name_ru='Гравелер' WHERE pokemon_id=75; 77 | UPDATE pokemon_info SET name_ru='Голем' WHERE pokemon_id=76; 78 | UPDATE pokemon_info SET name_ru='Понита' WHERE pokemon_id=77; 79 | UPDATE pokemon_info SET name_ru='Рапидаш' WHERE pokemon_id=78; 80 | UPDATE pokemon_info SET name_ru='Слоупок' WHERE pokemon_id=79; 81 | UPDATE pokemon_info SET name_ru='Слоубро' WHERE pokemon_id=80; 82 | UPDATE pokemon_info SET name_ru='Магнемайт' WHERE pokemon_id=81; 83 | UPDATE pokemon_info SET name_ru='Магнетон' WHERE pokemon_id=82; 84 | UPDATE pokemon_info SET name_ru='Фарфетчд' WHERE pokemon_id=83; 85 | UPDATE pokemon_info SET name_ru='Додуо' WHERE pokemon_id=84; 86 | UPDATE pokemon_info SET name_ru='Додрио' WHERE pokemon_id=85; 87 | UPDATE pokemon_info SET name_ru='Сил' WHERE pokemon_id=86; 88 | UPDATE pokemon_info SET name_ru='Дьюгонг' WHERE pokemon_id=87; 89 | UPDATE pokemon_info SET name_ru='Граймер' WHERE pokemon_id=88; 90 | UPDATE pokemon_info SET name_ru='Мак' WHERE pokemon_id=89; 91 | UPDATE pokemon_info SET name_ru='Шеллдер' WHERE pokemon_id=90; 92 | UPDATE pokemon_info SET name_ru='Клойстер' WHERE pokemon_id=91; 93 | UPDATE pokemon_info SET name_ru='Гастли' WHERE pokemon_id=92; 94 | UPDATE pokemon_info SET name_ru='Хонтер' WHERE pokemon_id=93; 95 | UPDATE pokemon_info SET name_ru='Генгар' WHERE pokemon_id=94; 96 | UPDATE pokemon_info SET name_ru='Оникс' WHERE pokemon_id=95; 97 | UPDATE pokemon_info SET name_ru='Драузи' WHERE pokemon_id=96; 98 | UPDATE pokemon_info SET name_ru='Гипно' WHERE pokemon_id=97; 99 | UPDATE pokemon_info SET name_ru='Крабби' WHERE pokemon_id=98; 100 | UPDATE pokemon_info SET name_ru='Кинглер' WHERE pokemon_id=99; 101 | UPDATE pokemon_info SET name_ru='Волторб' WHERE pokemon_id=100; 102 | UPDATE pokemon_info SET name_ru='Электрод' WHERE pokemon_id=101; 103 | UPDATE pokemon_info SET name_ru='Эксегкьют' WHERE pokemon_id=102; 104 | UPDATE pokemon_info SET name_ru='Экзегкьютор' WHERE pokemon_id=103; 105 | UPDATE pokemon_info SET name_ru='Кьюбон' WHERE pokemon_id=104; 106 | UPDATE pokemon_info SET name_ru='Маровак' WHERE pokemon_id=105; 107 | UPDATE pokemon_info SET name_ru='Хитмонли' WHERE pokemon_id=106; 108 | UPDATE pokemon_info SET name_ru='Хитмончан' WHERE pokemon_id=107; 109 | UPDATE pokemon_info SET name_ru='Ликитанг' WHERE pokemon_id=108; 110 | UPDATE pokemon_info SET name_ru='Коффинг' WHERE pokemon_id=109; 111 | UPDATE pokemon_info SET name_ru='Визинг' WHERE pokemon_id=110; 112 | UPDATE pokemon_info SET name_ru='Райхорн' WHERE pokemon_id=111; 113 | UPDATE pokemon_info SET name_ru='Райдон' WHERE pokemon_id=112; 114 | UPDATE pokemon_info SET name_ru='Ченси' WHERE pokemon_id=113; 115 | UPDATE pokemon_info SET name_ru='Тангела' WHERE pokemon_id=114; 116 | UPDATE pokemon_info SET name_ru='Кангасхан' WHERE pokemon_id=115; 117 | UPDATE pokemon_info SET name_ru='Хорси' WHERE pokemon_id=116; 118 | UPDATE pokemon_info SET name_ru='Сидра' WHERE pokemon_id=117; 119 | UPDATE pokemon_info SET name_ru='Голдин' WHERE pokemon_id=118; 120 | UPDATE pokemon_info SET name_ru='Сикинг' WHERE pokemon_id=119; 121 | UPDATE pokemon_info SET name_ru='Старью' WHERE pokemon_id=120; 122 | UPDATE pokemon_info SET name_ru='Старми' WHERE pokemon_id=121; 123 | UPDATE pokemon_info SET name_ru='Мистер Майм' WHERE pokemon_id=122; 124 | UPDATE pokemon_info SET name_ru='Скайтер' WHERE pokemon_id=123; 125 | UPDATE pokemon_info SET name_ru='Джинкс' WHERE pokemon_id=124; 126 | UPDATE pokemon_info SET name_ru='Электабазз' WHERE pokemon_id=125; 127 | UPDATE pokemon_info SET name_ru='Магмар' WHERE pokemon_id=126; 128 | UPDATE pokemon_info SET name_ru='Пинсир' WHERE pokemon_id=127; 129 | UPDATE pokemon_info SET name_ru='Таурос' WHERE pokemon_id=128; 130 | UPDATE pokemon_info SET name_ru='Мэджикарп' WHERE pokemon_id=129; 131 | UPDATE pokemon_info SET name_ru='Гиарадос' WHERE pokemon_id=130; 132 | UPDATE pokemon_info SET name_ru='Лапрас' WHERE pokemon_id=131; 133 | UPDATE pokemon_info SET name_ru='Дитто' WHERE pokemon_id=132; 134 | UPDATE pokemon_info SET name_ru='Иви' WHERE pokemon_id=133; 135 | UPDATE pokemon_info SET name_ru='Вапореон' WHERE pokemon_id=134; 136 | UPDATE pokemon_info SET name_ru='Джолтеон' WHERE pokemon_id=135; 137 | UPDATE pokemon_info SET name_ru='Флареон' WHERE pokemon_id=136; 138 | UPDATE pokemon_info SET name_ru='Поригон' WHERE pokemon_id=137; 139 | UPDATE pokemon_info SET name_ru='Оманайт' WHERE pokemon_id=138; 140 | UPDATE pokemon_info SET name_ru='Омастар' WHERE pokemon_id=139; 141 | UPDATE pokemon_info SET name_ru='Кабуто' WHERE pokemon_id=140; 142 | UPDATE pokemon_info SET name_ru='Кабутопс' WHERE pokemon_id=141; 143 | UPDATE pokemon_info SET name_ru='Аэродактиль' WHERE pokemon_id=142; 144 | UPDATE pokemon_info SET name_ru='Снорлакс' WHERE pokemon_id=143; 145 | UPDATE pokemon_info SET name_ru='Артикуно' WHERE pokemon_id=144; 146 | UPDATE pokemon_info SET name_ru='Запдос' WHERE pokemon_id=145; 147 | UPDATE pokemon_info SET name_ru='Молтрес' WHERE pokemon_id=146; 148 | UPDATE pokemon_info SET name_ru='Дратини' WHERE pokemon_id=147; 149 | UPDATE pokemon_info SET name_ru='Драгонэйр' WHERE pokemon_id=148; 150 | UPDATE pokemon_info SET name_ru='Драгонайт' WHERE pokemon_id=149; 151 | UPDATE pokemon_info SET name_ru='Мью' WHERE pokemon_id=150; 152 | UPDATE pokemon_info SET name_ru='Мьюту' WHERE pokemon_id=151; 153 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pokelyzer", 3 | "version": "v1.0.0-alpha", 4 | "description": "Pokelyzer is a database and data model for doing geospatial analysis and regular analytics on Pokemon Go data.", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node app.js" 9 | }, 10 | "author": "Ryan Brideau", 11 | "license": "MIT", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/Brideau/pokelyzer" 15 | }, 16 | "dependencies": { 17 | "body-parser": "^1.15.2", 18 | "express": "^4.14.0", 19 | "gaussian": "^1.1.0", 20 | "moment": "^2.14.1", 21 | "pg": "^6.0.3" 22 | }, 23 | "devDependencies": {} 24 | } 25 | -------------------------------------------------------------------------------- /patches/2016-07-26-dateKeyTypePatch.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE date_dimension ALTER COLUMN date_key TYPE integer USING (date_key::integer); -------------------------------------------------------------------------------- /patches/2016-07-28-dupePatch.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM spotted_pokemon USING spotted_pokemon sp2 2 | WHERE spotted_pokemon.encounter_id = sp2.encounter_id AND spotted_pokemon.id > sp2.id; 3 | ALTER TABLE spotted_pokemon ADD CONSTRAINT encounter_id_unique UNIQUE (encounter_id); -------------------------------------------------------------------------------- /patches/2016-07-30-eraPatch.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE public.spotted_pokemon ADD COLUMN pokemon_go_era integer; 2 | 3 | UPDATE public.spotted_pokemon 4 | SET pokemon_go_era = '1' 5 | WHERE hidden_time_utc < '2016-07-29 15:00:00'; 6 | 7 | UPDATE public.spotted_pokemon 8 | SET pokemon_go_era = '2' 9 | WHERE hidden_time_utc >= '2016-07-29 15:00:00'; -------------------------------------------------------------------------------- /patches/2016-07-30-metaPatch.sql: -------------------------------------------------------------------------------- 1 | -- Create a new table for storing metadata about the schema 2 | CREATE TABLE public._meta ( 3 | id serial, 4 | db_version text, 5 | last_update date 6 | ); 7 | INSERT INTO _meta (db_version, last_update) VALUES ('v0.5', '2016-07-30'); 8 | 9 | -- Add a new column that stores the version of the database used when the row was recorded 10 | 11 | ALTER TABLE spotted_pokemon ADD COLUMN meta_db_version text DEFAULT 'not versioned'; 12 | 13 | CREATE OR REPLACE FUNCTION get_db_version() 14 | RETURNS trigger 15 | LANGUAGE plpgsql 16 | SECURITY DEFINER 17 | AS $BODY$ 18 | DECLARE 19 | payload text; 20 | BEGIN 21 | NEW.meta_db_version = (SELECT db_version FROM _meta ORDER BY id DESC LIMIT 1); 22 | RETURN NEW; 23 | END 24 | $BODY$; 25 | 26 | CREATE TRIGGER get_db_version_trigger 27 | BEFORE INSERT OR UPDATE 28 | ON spotted_pokemon 29 | FOR EACH ROW 30 | EXECUTE PROCEDURE get_db_version(); 31 | 32 | -- Log the time each record was recorded 33 | 34 | ALTER TABLE spotted_pokemon ADD COLUMN meta_row_insertion_time timestamp; 35 | 36 | CREATE OR REPLACE FUNCTION get_row_insertion_time() 37 | RETURNS trigger 38 | LANGUAGE plpgsql 39 | SECURITY DEFINER 40 | AS $BODY$ 41 | DECLARE 42 | payload text; 43 | BEGIN 44 | NEW.meta_row_insertion_time = timezone('UTC', CURRENT_TIMESTAMP); 45 | RETURN NEW; 46 | END 47 | $BODY$; 48 | 49 | CREATE TRIGGER row_insertion_time_trigger 50 | BEFORE INSERT OR UPDATE 51 | ON spotted_pokemon 52 | FOR EACH ROW 53 | EXECUTE PROCEDURE get_row_insertion_time(); 54 | -------------------------------------------------------------------------------- /patches/2016-08-05-timezonePatch.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO _meta (db_version, last_update) VALUES ('v1.3-alpha', '2016-08-03'); 2 | 3 | -- Set the timezone in the postgresql.conf file. To find out the long-form name to use, try the following command using the abbreviation. 4 | -- SELECT * FROM pg_timezone_names WHERE abbrev = 'PDT'; 5 | 6 | 7 | -- Drop and replace the existing functions so that we replace them with simplified versions. 8 | 9 | DROP TRIGGER compute_point ON spotted_pokemon; 10 | DROP TRIGGER compute_point_jittered ON spotted_pokemon; 11 | DROP TRIGGER create_datekey ON spotted_pokemon; 12 | DROP TRIGGER create_timekey ON spotted_pokemon; 13 | DROP TRIGGER get_db_version_trigger ON spotted_pokemon; 14 | DROP TRIGGER row_insertion_time_trigger ON spotted_pokemon; 15 | 16 | DROP FUNCTION create_datekey_fn(); 17 | DROP FUNCTION create_point_from_lon_lat(); 18 | DROP FUNCTION create_point_from_lon_lat_jit(); 19 | DROP FUNCTION create_timekey_fn(); 20 | DROP FUNCTION get_db_version(); 21 | DROP FUNCTION get_row_insertion_time(); 22 | 23 | -- Cleans up some of the column types since it doesn't benefit us to us varchars in postgres 24 | ALTER TABLE public.spotted_pokemon ALTER COLUMN encounter_id TYPE text; 25 | ALTER TABLE public.spotted_pokemon ALTER COLUMN spawnpoint_id TYPE text; 26 | ALTER TABLE public.spotted_pokemon ALTER COLUMN pokemon_go_era TYPE smallint; 27 | 28 | 29 | -- Create a new timestamp column from the UTC column based on the timezone of the database 30 | ALTER TABLE public.spotted_pokemon ADD COLUMN hidden_time_local TIMESTAMP WITH TIME ZONE; 31 | ALTER TABLE public.spotted_pokemon ADD COLUMN time_key_local smallint; 32 | ALTER TABLE public.spotted_pokemon ADD COLUMN date_key_local integer; 33 | 34 | CREATE INDEX spotted_pokemon_date_key 35 | ON public.spotted_pokemon 36 | USING btree 37 | (date_key); 38 | 39 | CREATE INDEX spotted_pokemon_time_key 40 | ON public.spotted_pokemon 41 | USING btree 42 | (time_key); 43 | 44 | CREATE INDEX spotted_pokemon_date_key_local 45 | ON public.spotted_pokemon 46 | USING btree 47 | (date_key_local); 48 | 49 | CREATE INDEX spotted_pokemon_time_key_local 50 | ON public.spotted_pokemon 51 | USING btree 52 | (time_key_local); 53 | 54 | -- Add geospatial data to each row 55 | 56 | CREATE OR REPLACE FUNCTION create_geospatial_data_fn() 57 | RETURNS trigger 58 | LANGUAGE plpgsql 59 | SECURITY DEFINER 60 | AS $BODY$ 61 | BEGIN 62 | NEW.geo_point = St_SetSRID(ST_MakePoint(NEW.longitude, NEW.latitude), 4326); 63 | NEW.geo_point_jittered = St_SetSRID(ST_MakePoint(NEW.longitude_jittered, NEW.latitude_jittered), 4326); 64 | RETURN NEW; 65 | END 66 | $BODY$; 67 | 68 | CREATE TRIGGER create_geospatial_data 69 | BEFORE INSERT OR UPDATE 70 | ON spotted_pokemon 71 | FOR EACH ROW 72 | EXECUTE PROCEDURE create_geospatial_data_fn(); 73 | 74 | -- Add data and time keys to each row 75 | 76 | CREATE OR REPLACE FUNCTION add_date_time_keys_fn() 77 | RETURNS trigger 78 | LANGUAGE plpgsql 79 | SECURITY DEFINER 80 | AS $BODY$ 81 | BEGIN 82 | NEW.date_key = NULLIF(to_char(NEW.hidden_time_utc, 'YYYYMMDD'), '')::int; 83 | NEW.time_key = to_char(NEW.hidden_time_utc, 'MI')::int + (to_char(NEW.hidden_time_utc, 'HH24')::int * 60); 84 | NEW.hidden_time_local = NEW.hidden_time_utc AT TIME ZONE 'UTC'; 85 | NEW.time_key_local = to_char(NEW.hidden_time_local, 'MI')::int + (to_char(NEW.hidden_time_local, 'HH24')::int * 60); 86 | NEW.date_key_local = NULLIF(to_char(NEW.hidden_time_local, 'YYYYMMDD'), '')::int; 87 | RETURN NEW; 88 | END 89 | $BODY$; 90 | 91 | CREATE TRIGGER add_date_time_keys 92 | BEFORE INSERT OR UPDATE 93 | ON spotted_pokemon 94 | FOR EACH ROW 95 | EXECUTE PROCEDURE add_date_time_keys_fn(); 96 | 97 | --- Add metadata to each row 98 | 99 | CREATE OR REPLACE FUNCTION get_meta_data_fn() 100 | RETURNS trigger 101 | LANGUAGE plpgsql 102 | SECURITY DEFINER 103 | AS $BODY$ 104 | BEGIN 105 | NEW.meta_db_version = (SELECT db_version FROM _meta ORDER BY id DESC LIMIT 1); 106 | NEW.meta_row_insertion_time = timezone('UTC', CURRENT_TIMESTAMP); 107 | RETURN NEW; 108 | END 109 | $BODY$; 110 | 111 | CREATE TRIGGER get_meta_data 112 | BEFORE INSERT 113 | ON spotted_pokemon 114 | FOR EACH ROW 115 | EXECUTE PROCEDURE get_meta_data_fn(); 116 | 117 | UPDATE public.spotted_pokemon SET hidden_time_utc = CAST(to_timestamp(hidden_time_unix_s) AT TIME ZONE 'UTC' AS timestamp); 118 | 119 | 120 | -- Add new views of the original date and time tables in case people want to use both. Also help with user-friendliness in Tableau. 121 | 122 | CREATE VIEW date_dimension_local AS SELECT 123 | date_key AS date_key_local, 124 | full_date, 125 | day_of_week, 126 | day_of_week_name, 127 | day_of_week_name_abbrev, 128 | day_of_month, 129 | day_number_overall, 130 | weekday_flag, 131 | week_number, 132 | week_number_overall, 133 | week_begin_date, 134 | week_begin_date_key, 135 | month_number, 136 | month_number_overall, 137 | month, 138 | month_abbrev, 139 | quarter, 140 | year, 141 | year_month, 142 | month_end_flag 143 | FROM date_dimension; 144 | 145 | CREATE VIEW time_dimension_local AS SELECT 146 | time_key AS time_key_local, 147 | time_label_24, 148 | time_label_12, 149 | time_interval_15min, 150 | time_interval_30min, 151 | time_interval_60min, 152 | label_hh, 153 | label_hh24, 154 | label_15min_24, 155 | label_30min_24, 156 | label_60min_24, 157 | label_15min_12, 158 | label_30min_12, 159 | label_60min_12 160 | FROM time_dimension; 161 | 162 | SELECT * 163 | FROM spotted_pokemon 164 | ORDER BY id DESC LIMIT 5; 165 | 166 | -- Fix the bug where I forgot to decode the encounter_id 167 | 168 | -- First turn off the unique constraint that we have so we don't get conflicts during this update 169 | ALTER TABLE spotted_pokemon DROP CONSTRAINT encounter_spawnpoint_id_unique; 170 | 171 | -- Then decode all the rows that aren't numeric 172 | UPDATE public.spotted_pokemon 173 | SET encounter_id = decode(encounter_id, 'base64') 174 | WHERE NOT encounter_id ~ '^([0-9]+[.]?[0-9]*|[.][0-9]+)$'; 175 | 176 | -- Then delete any duplicates based on the encounter_id and spawnpoint_id 177 | DELETE FROM public.spotted_pokemon 178 | WHERE id IN (SELECT id 179 | FROM (SELECT id, ROW_NUMBER() OVER (partition BY encounter_id, spawnpoint_id ORDER BY id) AS rnum 180 | FROM public.spotted_pokemon ) AS t 181 | WHERE t.rnum > 1); 182 | 183 | -- Then add the constraint back 184 | ALTER TABLE public.spotted_pokemon 185 | ADD CONSTRAINT encounter_spawnpoint_id_unique UNIQUE(encounter_id, spawnpoint_id); 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /patches/pokemon_info_table_patch_2.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Brideau/pokelyzer/a0468f41935cee29c5ae1465a4bf169b8bf8c97c/patches/pokemon_info_table_patch_2.tar -------------------------------------------------------------------------------- /pokelyze_sql.sql: -------------------------------------------------------------------------------- 1 | ----------- The main fact table, spotted pokemon------------- 2 | 3 | CREATE TABLE public.spotted_pokemon( 4 | id bigserial NOT NULL, 5 | encounter_id varchar(40), 6 | last_modified_time bigint, 7 | time_until_hidden_ms bigint, 8 | hidden_time_unix_s bigint, 9 | hidden_time_utc timestamp without time zone, 10 | spawnpoint_id varchar(20), 11 | longitude double precision, 12 | latitude double precision, 13 | pokemon_id smallint, 14 | time_key smallint, 15 | date_key integer, 16 | longitude_jittered double precision, 17 | latitude_jittered double precision, 18 | geo_point geometry, 19 | geo_point_jittered geometry, 20 | pokemon_go_era integer, 21 | meta_db_version text DEFAULT 'not versioned'::text, 22 | meta_row_insertion_time timestamp without time zone, 23 | CONSTRAINT encounter_id_unique UNIQUE (encounter_id), 24 | CONSTRAINT id_primary_key PRIMARY KEY (id) 25 | 26 | ); 27 | ALTER TABLE public.spotted_pokemon 28 | OWNER TO pokemon_go_role; 29 | 30 | CREATE INDEX point_index 31 | ON public.spotted_pokemon 32 | USING gist 33 | (geo_point); 34 | 35 | CREATE INDEX jitter_index 36 | ON public.spotted_pokemon 37 | USING gist 38 | (geo_point_jittered); 39 | 40 | CREATE INDEX latitude_index 41 | ON public.spotted_pokemon 42 | USING btree 43 | (latitude); 44 | 45 | CREATE INDEX latitude_jit_index 46 | ON public.spotted_pokemon 47 | USING btree 48 | (latitude_jittered); 49 | 50 | CREATE INDEX longitude_index 51 | ON public.spotted_pokemon 52 | USING btree 53 | (longitude); 54 | 55 | CREATE INDEX longitude_jit_index 56 | ON public.spotted_pokemon 57 | USING btree 58 | (longitude_jittered); 59 | 60 | CREATE INDEX pokemon_id_index 61 | ON public.spotted_pokemon 62 | USING btree 63 | (pokemon_id); 64 | 65 | CREATE INDEX spotted_pokemon_date_key 66 | ON public.spotted_pokemon 67 | USING btree 68 | (date_key); 69 | 70 | CREATE INDEX spotted_pokemon_time_key 71 | ON public.spotted_pokemon 72 | USING btree 73 | (time_key); 74 | 75 | -------- The pokemon info dimension table ------------ 76 | 77 | CREATE TABLE public.pokemon_info 78 | ( 79 | pokemon_id bigint NOT NULL, 80 | name text, 81 | classification text, 82 | type_1 text, 83 | type_2 text, 84 | weight double precision, 85 | height double precision, 86 | CONSTRAINT pokemon_info_pkey PRIMARY KEY (pokemon_id) 87 | ); 88 | 89 | ALTER TABLE public.pokemon_info 90 | OWNER TO pokemon_go_role; 91 | CREATE INDEX pokemon_info_pokemon_id_idx 92 | ON public.pokemon_info 93 | USING btree 94 | (pokemon_id); 95 | 96 | CREATE INDEX pokemon_info_pokemon_name_index 97 | ON public.pokemon_info 98 | USING btree 99 | (name); 100 | 101 | -------- The meta table for recording schema versions 102 | 103 | CREATE TABLE public._meta ( 104 | id serial, 105 | db_version text, 106 | last_update date 107 | ); 108 | ALTER TABLE public.public 109 | OWNER TO pokemon_go_role; 110 | INSERT INTO _meta (db_version, last_update) VALUES ('v1.0.1-alpha', '2016-08-01'); 111 | 112 | 113 | --- The time and date dimensions are created with a python script 114 | 115 | 116 | -- Create a point from the latitude and longitude of pokemon 117 | 118 | CREATE OR REPLACE FUNCTION create_point_from_lon_lat() 119 | RETURNS trigger 120 | LANGUAGE plpgsql 121 | SECURITY DEFINER 122 | AS $BODY$ 123 | DECLARE 124 | payload text; 125 | BEGIN 126 | NEW.geo_point = St_SetSRID(ST_MakePoint(NEW.longitude, NEW.latitude), 4326); 127 | RETURN NEW; 128 | END 129 | $BODY$; 130 | 131 | CREATE TRIGGER compute_point 132 | BEFORE INSERT OR UPDATE 133 | ON spotted_pokemon 134 | FOR EACH ROW 135 | EXECUTE PROCEDURE create_point_from_lon_lat(); 136 | 137 | -- Create a point from the JITTERED latitude and longitude of pokemon 138 | 139 | CREATE OR REPLACE FUNCTION create_point_from_lon_lat_jit() 140 | RETURNS trigger 141 | LANGUAGE plpgsql 142 | SECURITY DEFINER 143 | AS $BODY$ 144 | DECLARE 145 | payload text; 146 | BEGIN 147 | NEW.geo_point_jittered = St_SetSRID(ST_MakePoint(NEW.longitude_jittered, NEW.latitude_jittered), 4326); 148 | RETURN NEW; 149 | END 150 | $BODY$; 151 | 152 | CREATE TRIGGER compute_point_jittered 153 | BEFORE INSERT OR UPDATE 154 | ON spotted_pokemon 155 | FOR EACH ROW 156 | EXECUTE PROCEDURE create_point_from_lon_lat_jit(); 157 | 158 | -- Create a date key from the timestamp to be used with the date dimension table 159 | 160 | CREATE OR REPLACE FUNCTION create_datekey_fn() 161 | RETURNS trigger 162 | LANGUAGE plpgsql 163 | SECURITY DEFINER 164 | AS $BODY$ 165 | DECLARE 166 | payload text; 167 | BEGIN 168 | NEW.date_key = NULLIF(to_char(NEW.hidden_time_utc, 'YYYYMMDD'), '')::int; 169 | RETURN NEW; 170 | END 171 | $BODY$; 172 | 173 | DROP TRIGGER IF EXISTS create_datekey ON spotted_pokemon; 174 | CREATE TRIGGER create_datekey 175 | BEFORE INSERT OR UPDATE 176 | ON spotted_pokemon 177 | FOR EACH ROW 178 | EXECUTE PROCEDURE create_datekey_fn(); 179 | 180 | -- Create a time key from the timestamp to be used with the time dimension table 181 | 182 | CREATE OR REPLACE FUNCTION create_timekey_fn() 183 | RETURNS trigger 184 | LANGUAGE plpgsql 185 | SECURITY DEFINER 186 | AS $BODY$ 187 | DECLARE 188 | payload text; 189 | BEGIN 190 | NEW.time_key = to_char(NEW.hidden_time_utc, 'MI')::int + (to_char(NEW.hidden_time_utc, 'HH24')::int * 60); 191 | RETURN NEW; 192 | END 193 | $BODY$; 194 | 195 | DROP TRIGGER IF EXISTS create_timekey ON spotted_pokemon; 196 | CREATE TRIGGER create_timekey 197 | BEFORE INSERT OR UPDATE 198 | ON spotted_pokemon 199 | FOR EACH ROW 200 | EXECUTE PROCEDURE create_timekey_fn(); 201 | 202 | CREATE OR REPLACE FUNCTION get_db_version() 203 | RETURNS trigger 204 | LANGUAGE plpgsql 205 | SECURITY DEFINER 206 | AS $BODY$ 207 | DECLARE 208 | payload text; 209 | BEGIN 210 | NEW.meta_db_version = (SELECT db_version FROM _meta ORDER BY id DESC LIMIT 1); 211 | RETURN NEW; 212 | END 213 | $BODY$; 214 | 215 | CREATE TRIGGER get_db_version_trigger 216 | BEFORE INSERT OR UPDATE 217 | ON spotted_pokemon 218 | FOR EACH ROW 219 | EXECUTE PROCEDURE get_db_version(); 220 | 221 | -- Log the time each record was recorded 222 | 223 | CREATE OR REPLACE FUNCTION get_row_insertion_time() 224 | RETURNS trigger 225 | LANGUAGE plpgsql 226 | SECURITY DEFINER 227 | AS $BODY$ 228 | DECLARE 229 | payload text; 230 | BEGIN 231 | NEW.meta_row_insertion_time = timezone('UTC', CURRENT_TIMESTAMP); 232 | RETURN NEW; 233 | END 234 | $BODY$; 235 | 236 | CREATE TRIGGER row_insertion_time_trigger 237 | BEFORE INSERT OR UPDATE 238 | ON spotted_pokemon 239 | FOR EACH ROW 240 | EXECUTE PROCEDURE get_row_insertion_time(); 241 | -------------------------------------------------------------------------------- /pokemon_go_db_backup.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Brideau/pokelyzer/a0468f41935cee29c5ae1465a4bf169b8bf8c97c/pokemon_go_db_backup.tar -------------------------------------------------------------------------------- /windowsBatch.bat: -------------------------------------------------------------------------------- 1 | set DB_NAME=pokemon_go 2 | set DB_USER=pokemon_go_role 3 | set DB_PASS=[Your Pass] 4 | set DB_PORT=5432 5 | set WS_PORT=9876 6 | set ERA=2 --------------------------------------------------------------------------------