2019-09-12 20:53:42 +00:00
from flask import current_app
2019-02-10 17:39:06 +00:00
from flask . cli import AppGroup
import click
2019-01-01 19:13:08 +00:00
2019-09-14 06:27:35 +00:00
from datetime import datetime
2019-01-01 19:13:08 +00:00
from sqlalchemy . sql import func
2017-10-03 11:31:24 +00:00
2020-12-12 12:48:05 +00:00
from app . model import SenderPosition
2019-08-31 08:14:41 +00:00
from app . utils import get_airports , get_days
2020-10-27 19:46:14 +00:00
from app . collect . timescaledb_views import create_timescaledb_views , create_views
2020-12-12 12:48:05 +00:00
from app . collect . database import read_ddb , read_flarmnet , merge_sender_infos
2019-03-11 22:26:01 +00:00
2019-08-31 08:14:41 +00:00
from app import db
2019-02-10 17:39:06 +00:00
2019-08-31 08:14:41 +00:00
user_cli = AppGroup ( " database " )
2019-02-10 17:39:06 +00:00
user_cli . help = " Database creation and handling. "
2015-11-15 08:10:46 +00:00
2016-01-31 01:25:21 +00:00
ALEMBIC_CONFIG_FILE = " alembic.ini "
2015-11-15 18:31:58 +00:00
2019-01-01 19:13:08 +00:00
def get_database_days ( start , end ) :
""" Returns the first and the last day in aircraft_beacons table. """
if start is None and end is None :
2020-10-27 19:46:14 +00:00
days_from_db = db . session . query ( func . min ( SenderPosition . timestamp ) . label ( " first_day " ) , func . max ( SenderPosition . timestamp ) . label ( " last_day " ) ) . one ( )
2019-01-01 19:13:08 +00:00
start = days_from_db [ 0 ] . date ( )
end = days_from_db [ 1 ] . date ( )
else :
2019-01-05 10:10:10 +00:00
start = datetime . strptime ( start , " % Y- % m- %d " ) . date ( )
end = datetime . strptime ( end , " % Y- % m- %d " ) . date ( )
2019-01-01 19:13:08 +00:00
days = get_days ( start , end )
return days
2019-08-31 08:14:41 +00:00
@user_cli.command ( " info " )
2019-02-25 19:00:51 +00:00
def info ( ) :
2019-09-12 20:53:42 +00:00
print ( current_app . config )
print ( current_app . config [ " SQLALCHEMY_DATABASE_URI " ] )
2019-02-25 19:00:51 +00:00
2019-08-31 08:14:41 +00:00
@user_cli.command ( " init " )
2015-11-15 08:10:46 +00:00
def init ( ) :
2020-11-17 13:58:23 +00:00
""" Initialize the database (with PostGIS and TimescaleDB extensions). """
2015-12-09 02:37:25 +00:00
2016-01-29 01:38:55 +00:00
from alembic . config import Config
from alembic import command
2020-11-17 13:58:23 +00:00
# Create PostGIS and PostGIS extensions
2019-08-31 08:14:41 +00:00
db . session . execute ( " CREATE EXTENSION IF NOT EXISTS postgis; " )
db . session . execute ( " CREATE EXTENSION IF NOT EXISTS btree_gist; " )
2020-11-17 13:58:23 +00:00
db . session . execute ( " CREATE EXTENSION IF NOT EXISTS timescaledb; " )
2019-02-10 17:39:06 +00:00
db . session . commit ( )
2015-11-15 08:23:57 +00:00
2020-11-17 13:58:23 +00:00
# Create Scheme
db . create_all ( )
2015-11-15 08:23:57 +00:00
2020-11-17 13:58:23 +00:00
# Change (sender|receiver)_positions to TimescaleDB table
2020-10-27 19:46:14 +00:00
db . session . execute ( " SELECT create_hypertable( ' sender_positions ' , ' reference_timestamp ' , chunk_time_interval => interval ' 3 hours ' , if_not_exists => TRUE); " )
db . session . execute ( " SELECT create_hypertable( ' receiver_positions ' , ' reference_timestamp ' , chunk_time_interval => interval ' 1 day ' , if_not_exists => TRUE); " )
2019-02-10 17:39:06 +00:00
db . session . commit ( )
2019-01-04 14:06:11 +00:00
2020-11-17 13:58:23 +00:00
print ( " Initialized the database (with PostGIS and TimescaleDB extensions). " )
2016-01-31 01:25:21 +00:00
2019-08-31 08:14:41 +00:00
@user_cli.command ( " drop " )
@click.option ( " --sure " , default = " n " )
2019-02-25 19:00:51 +00:00
def drop ( sure ) :
2016-01-12 17:36:08 +00:00
""" Drop all tables. """
2019-08-31 08:14:41 +00:00
if sure == " y " :
2019-03-04 21:14:13 +00:00
db . drop_all ( )
2019-08-31 08:14:41 +00:00
print ( " Dropped all tables. " )
2016-01-12 17:36:08 +00:00
else :
print ( " Add argument ' --sure y ' to drop all tables. " )
2019-08-31 08:14:41 +00:00
@user_cli.command ( " import_ddb " )
2020-12-12 12:48:05 +00:00
@click.option ( ' --path ' , default = None , help = ' path to a local ddb file. ' )
def import_ddb ( path ) :
2015-12-09 02:41:58 +00:00
""" Import registered devices from the DDB. """
2015-11-24 07:20:28 +00:00
2020-12-12 12:48:05 +00:00
if path is None :
print ( " Import registered devices fom the DDB... " )
sender_info_dicts = read_ddb ( )
else :
print ( " Import registered devices from ' {} ' ... " . format ( path ) )
sender_info_dicts = read_ddb ( csv_file = path )
counter = merge_sender_infos ( sender_info_dicts )
2015-12-09 02:41:58 +00:00
print ( " Imported %i devices. " % counter )
2016-04-22 08:44:39 +00:00
2018-12-08 08:00:44 +00:00
2019-08-31 08:14:41 +00:00
@user_cli.command ( " import_flarmnet " )
@click.argument ( " path " )
2018-12-08 08:00:44 +00:00
def import_flarmnet ( path = None ) :
2018-10-21 15:34:03 +00:00
""" Import registered devices from a local file. """
print ( " Import registered devices from ' {} ' ... " . format ( " internet " if path is None else path ) )
2020-12-12 12:48:05 +00:00
sender_info_dicts = read_flarmnet ( path = path )
counter = merge_sender_infos ( sender_info_dicts )
2018-10-21 15:34:03 +00:00
print ( " Imported %i devices. " % counter )
2016-04-22 08:44:39 +00:00
2018-12-08 08:00:44 +00:00
2019-08-31 08:14:41 +00:00
@user_cli.command ( " import_airports " )
@click.argument ( " path " )
def import_airports ( path = " tests/SeeYou.cup " ) :
2016-04-22 08:44:39 +00:00
""" Import airports from a " .cup " file """
print ( " Import airports from ' {} ' ... " . format ( path ) )
airports = get_airports ( path )
2019-02-10 17:39:06 +00:00
db . session . bulk_save_objects ( airports )
db . session . commit ( )
2020-10-27 19:46:14 +00:00
# TODO: SRID 4087 ist nicht korrekt, aber spherical mercator 3857 wirft hier Fehler
db . session . execute ( " UPDATE airports AS a SET border = ST_Transform(ST_Buffer(ST_Transform(location, 4087), 1.5 * GREATEST(500, a.runway_length)), 4326); " )
2019-02-10 17:39:06 +00:00
db . session . commit ( )
2016-04-22 08:44:39 +00:00
print ( " Imported {} airports. " . format ( len ( airports ) ) )
2018-10-21 15:34:03 +00:00
2020-11-22 07:55:19 +00:00
2020-10-27 19:46:14 +00:00
@user_cli.command ( " create_timescaledb_views " )
def cmd_create_timescaledb_views ( ) :
""" Create TimescaleDB views. """
create_timescaledb_views ( )
print ( " Done " )
2020-11-22 07:55:19 +00:00
2020-10-27 19:46:14 +00:00
@user_cli.command ( " create_views " )
def cmd_create_views ( ) :
""" Create views. """
create_views ( )
print ( " Done " )