MobilityDB SQLAlchemy

22
MobilityDB SQLAlchemy Release 0.4 Bommakanti Krishna Chaitanya Apr 23, 2021

Transcript of MobilityDB SQLAlchemy

Page 1: MobilityDB SQLAlchemy

MobilityDB SQLAlchemyRelease 0.4

Bommakanti Krishna Chaitanya

Apr 23, 2021

Page 2: MobilityDB SQLAlchemy
Page 3: MobilityDB SQLAlchemy

CONTENTS:

1 Quickstart 11.1 Temporal data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Geometric data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Inserting TGeomPoint data, using movingpandas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.4 Querying data from MobilityDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.5 Using MobilityDB operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.6 Using MobilityDB ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.7 Making use of movingpandas Trajectory data structure . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 Operators 7

3 Installation 11

4 Indices and tables 13

Python Module Index 15

Index 17

i

Page 4: MobilityDB SQLAlchemy

ii

Page 5: MobilityDB SQLAlchemy

CHAPTER

ONE

QUICKSTART

1.1 Temporal data

mobilitydb-sqlalchemy lets you use pandas DataFrame (which are great for timeseries data) while you are in thePython world, and translates it back and for to temporal types defined in mobilitydb.

A point to note here is that we assume that the DataFrame’s columns are named “value” (except in case of TGeomPointwhere it is “geometry”) and “t” for the data and the timestamp respectively.

Here we show how we can store numeric data which changes over time (i.e. tfloat), using themobilitydb_sqlalchemy.types.TFloat.TFloat class.

Running the following code will create a new table with a tfloat column, and insert one row of hardcoded data into it.

1.1.1 Write data to MobilityDB

import datetimeimport pandas as pd

from mobilitydb_sqlalchemy import TFloatfrom sqlalchemy import Column, Integer, create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import sessionmaker

# Setup the engine and session, make sure you set the right url to connect to your→˓mobilitydb instanceengine = create_engine("postgresql://docker:docker@localhost:25432/mobilitydb",→˓echo=True)session = sessionmaker(bind=engine)()

# Setup and create the tables (only one in our case here)Base = declarative_base()

class TemporalFloats(Base):__tablename__ = "tfloat_test_001"id = Column(Integer, primary_key=True)tdata = Column(TFloat(True, False))

Base.metadata.create_all(engine)

# Prepare and insert the datadf = pd.DataFrame(

[

(continues on next page)

1

Page 6: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

(continued from previous page)

{"value": 0, "t": datetime.datetime(2018, 1, 1, 12, 0, 0)},{"value": 8.2, "t": datetime.datetime(2018, 1, 1, 12, 6, 0)},{"value": 6.6, "t": datetime.datetime(2018, 1, 1, 12, 10, 0)},{"value": 9.1, "t": datetime.datetime(2018, 1, 1, 12, 15, 0)},

]).set_index("t")row = TemporalFloats(tdata=df,)session.add(row)session.commit()

1.2 Geometric data

While creating the DataFrame, make sure the column is named “geometry” and not “value”. This is to maintaincompatibility with movingpandas. We can use Point objects from shapely for preparing the geometry data.

1.2.1 Writing

import datetimeimport pandas as pd

from mobilitydb_sqlalchemy import TGeomPointfrom shapely.geometry import Pointfrom sqlalchemy import Column, Integer, create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import sessionmaker

engine = create_engine("postgresql://docker:docker@db:25432/mobilitydb", echo=True)session = sessionmaker(bind=engine)()

Base = declarative_base()

class Trips(Base):__tablename__ = "trips_test_001"car_id = Column(Integer, primary_key=True)trip_id = Column(Integer, primary_key=True)trip = Column(TGeomPoint)

Base.metadata.create_all(engine)

# Prepare and insert the datadf = pd.DataFrame(

[{"geometry": Point(0, 0), "t": datetime.datetime(2012, 1, 1, 8, 0, 0),},{"geometry": Point(2, 0), "t": datetime.datetime(2012, 1, 1, 8, 10, 0),},{"geometry": Point(2, -1.9), "t": datetime.datetime(2012, 1, 1, 8, 15, 0),},

]).set_index("t")

trip = Trips(car_id=1, trip_id=1, trip=df,)session.add(trip)session.commit()

2 Chapter 1. Quickstart

Page 7: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

1.2.2 Querying

Listing 1: Example usage of the TGeomPoint class as a column in atable defined using SQLAlchemy’s declarative API

from mobilitydb_sqlalchemy import TGeomPoint

from sqlalchemy import Column, Integerfrom sqlalchemy.ext.declarative import declarative_baseBase = declarative_base()

class Trips(Base):__tablename__ = "test_table_trips_01"car_id = Column(Integer, primary_key=True)trip_id = Column(Integer, primary_key=True)trip = Column(TGeomPoint)

trips = session.query(Trips).all()

# Querying using MobilityDB functions, for example - valueAtTimestampsession.query(

Trips.car_id,func.asText(

func.valueAtTimestamp(Trips.trip, datetime.datetime(2012, 1, 1, 8, 10, 0))),

).all()

1.3 Inserting TGeomPoint data, using movingpandas

movingpandas is an optional dependency, but if installed, you can insert TGeomPoint data with Trajectory objectsdirectly. Just be sure to enable the flag use_movingpandas on the column beforehand.

import datetimeimport pandas as pdfrom geopandas import GeoDataFrameimport movingpandas as mpd

from mobilitydb_sqlalchemy import TGeomPointfrom shapely.geometry import Pointfrom sqlalchemy import Column, Integer, create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import sessionmaker

from fiona.crs import from_epsgCRS_METRIC = from_epsg(31256)

engine = create_engine("postgresql://docker:docker@db:25432/mobilitydb", echo=True)session = sessionmaker(bind=engine)()

Base = declarative_base()

class Trips(Base):__tablename__ = "trips_test_002"car_id = Column(Integer, primary_key=True)trip_id = Column(Integer, primary_key=True)

(continues on next page)

1.3. Inserting TGeomPoint data, using movingpandas 3

Page 8: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

(continued from previous page)

trip = Column(TGeomPoint(use_movingpandas=True))

Base.metadata.create_all(engine)

# Prepare and insert the datadf = pd.DataFrame(

[{"geometry": Point(0, 0), "t": datetime.datetime(2012, 1, 1, 8, 0, 0),},{"geometry": Point(2, 0), "t": datetime.datetime(2012, 1, 1, 8, 10, 0),},{"geometry": Point(2, -1.9), "t": datetime.datetime(2012, 1, 1, 8, 15, 0),},

]).set_index("t")geo_df = GeoDataFrame(df, crs=CRS_METRIC)

traj = mpd.Trajectory(geo_df, 1)# Note: In case you are depending on movingpandas 0.1 or lower,# you might need to do mpd.Trajectory(1, geo_df) instead

trip = Trips(car_id=1, trip_id=1, trip=traj,)session.add(trip)session.commit()

1.4 Querying data from MobilityDB

SQLAlchemy’s func is pretty generic and flexible, allowing us to use MobilityDB’s functions without needing anynew constructs.

Let’s take few example queries from MobilityDB’s documentation, and explain how we can achieve the same usingthis package.

from sqlalchemy import funcfrom shapely.wkt import loads

1.4.1 Value at a given timestamp

SELECT CarId, ST_AsText(valueAtTimestamp(Trip, timestamptz '2012-01-01 08:10:00'))→˓FROM Trips;-- 10;"POINT(2 0)"-- 20;"POINT(1 1)"

session.query(Trips.car_id,func.asText(

func.valueAtTimestamp(Trips.trip, datetime.datetime(2012, 1, 1, 8, 10, 0))),

).all()

4 Chapter 1. Quickstart

Page 9: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

1.4.2 Restriction to a given value

SELECT CarId, asText(atValue(Trip, 'Point(2 0)'))FROM Trips;-- 10;"{"[POINT(2 0)@2012-01-01 08:10:00+00]"}"-- 20; NULL

session.query(Trips.car_id,func.asText(func.atValue(Trips.trip, Point(2, 0).wkt)),

).all()

1.4.3 Restriction to a period

SELECT CarId, asText(atPeriod(Trip, '[2012-01-01 08:05:00,2012-01-01 08:10:00]'))FROM Trips;-- 10;"{[POINT(1 0)@2012-01-01 08:05:00+00, POINT(2 0)@2012-01-01 08:10:00+00]}"-- 20;"{[POINT(0 0)@2012-01-01 08:05:00+00, POINT(1 1)@2012-01-01 08:10:00+00]}"

session.query(Trips.car_id,func.asText(

func.atPeriod(Trips.trip, "[2012-01-01 08:05:00,2012-01-01 08:10:00]")),

).all()

1.4.4 Temporal distance

-- Temporal distanceSELECT T1.CarId, T2.CarId, T1.Trip <-> T2.TripFROM Trips T1, Trips T2WHERE T1.CarId < T2.CarId;-- 10;20;"{[1@2012-01-01 08:05:00+00, 1.4142135623731@2012-01-01 08:10:00+00, 1@2012-→˓01-01 08:15:00+00)}"

session.query(T1.c.car_id,T2.c.car_id,T1.c.trip.distance(T2.c.trip),

) \.filter(T1.c.car_id < T2.c.car_id,).all()

1.4. Querying data from MobilityDB 5

Page 10: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

1.5 Using MobilityDB operators

Listing 2: Example usage of the distance operator (‘<->’)

session.query(T1.c.car_id,T2.c.car_id,T1.c.trip.distance(T2.c.trip),

) \.filter(T1.c.car_id < T2.c.car_id,).all()

For exhaustive listing of operators, see operators page.

1.6 Using MobilityDB ranges

MobilityDB also allows you to store the temporal data in either open or closed intervals on either site. While this issupported by the package at the column level, because we use pandas DataFrame to hold the values once we load theminto python runtime, this data is lost, and hence not of much use. In future, this can be avoided with a better suitingdata structure to hold this data instead of relying on pandas.

However, to define a column which stores temporal data as a left closed, right open interval, ie. ‘[)’, it can be done asshown below:

class Trips(Base):trip_id = Column(Integer, primary_key=True)trip = Column(TGeomPoint(True, False))

1.7 Making use of movingpandas Trajectory data structure

TGeomPoint objects can also be optionally mapped to movingpandas Trajectory objects.

For this the optional dependency “movingpandas” needs to be installed.

poetry install -E movingpandas

After this, movingpandas can be enabled with a flag on the TGeomPoint column

class Trips(Base):trip_id = Column(Integer, primary_key=True)trip = Column(TGeomPoint(use_movingpandas=True))

6 Chapter 1. Quickstart

Page 11: MobilityDB SQLAlchemy

CHAPTER

TWO

OPERATORS

More details can be found in MobilityDB’s documentation itself: https://docs.mobilitydb.com/nightly/index.html

class mobilitydb_sqlalchemy.comparator.Comparator(expr)Bases: sqlalchemy.sql.type_api.Comparator

A custom comparator base class. It adds the ability to call spatial and temporal functions on columns that usethis kind of comparator. It also defines functions that map to operators supported by TBool, TInt, TFloatand TGeomPoint columns.

always_different_from(other)The “@<>” operator.

always_equal_to(other)The “%=” operator.

Is lhs always equal to the rhs?

The function does not take into account whether the bounds are inclusive or not.

always_greater_than(other)The “%>” operator.

always_greater_than_or_equal_to(other)The “%>=” operator.

always_less_than(other)The “%<” operator.

always_less_than_or_equal_to(other)The “%<=” operator.

bbox_always_after(other)The “<<#” operator.

bbox_always_before(other)The “<<#” operator.

bbox_always_strictly_greater_than(other)The “>>” operator.

bbox_always_strictly_less_than(other)The “<<” operator.

bbox_contained(other)The “<@” operator.

bbox_contains(other)The “@>” operator.

7

Page 12: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

bbox_does_not_extend_above(other)The “|&>” operator.

bbox_does_not_extend_below(other)The “&<|” operator.

bbox_does_not_extend_in_back(other)The “/&>” operator.

bbox_does_not_extend_in_front(other)The “&</” operator.

bbox_does_not_extend_to_left(other)The “&>” operator.

bbox_does_not_extend_to_right(other)The “&<” operator.

bbox_never_after(other)The “&<#” operator.

bbox_never_before(other)The “#&>” operator.

bbox_never_greater_than(other)The “&<” operator.

bbox_never_less_than(other)The “&>” operator.

bbox_strictly_above(other)The “|>>” operator.

bbox_strictly_below(other)The “<<|” operator.

bbox_strictly_in_back(other)The “/>>” operator.

bbox_strictly_in_front(other)The “<</” operator.

bbox_strictly_to_left(other)The “<<” operator.

bbox_strictly_to_right(other)The “>>” operator.

bboxes_equal(other)The “~=” operator.

bboxes_overlap(other)The “&&” operator.

distance(other)The “<->” operator.

ever_different_from(other)The “?<>” operator.

ever_equal_to(other)The “?=” operator.

Is lhs ever equal to the rhs?

8 Chapter 2. Operators

Page 13: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

The function does not take into account whether the bounds are inclusive or not.

ever_greater_than(other)The “?>” operator.

ever_greater_than_or_equal_to(other)The “?>=” operator.

ever_less_than(other)The “?<” operator.

ever_less_than_or_equal_to(other)The “?<=” operator.

expr

smallest_distance_ever_between(other)The “|=|” operator.

temporal_equal(other)The “#=” operator.

temporal_greater_than(other)The “#>” operator.

temporal_greater_than_or_equal_to(other)The “#>=” operator.

temporal_less_than(other)The “#<” operator.

temporal_less_than_or_equal_to(other)The “#<=” operator.

temporal_not_equal(other)The “#<>” operator.

type

MobilityDB extensions for SQLAlchemy.

Specifically, the following column types are provided, which can be used in SQLAlchemy models defined using thedeclarative API:

class mobilitydb_sqlalchemy.types.TGeomPoint

class mobilitydb_sqlalchemy.types.TFloat

class mobilitydb_sqlalchemy.types.TInt

class mobilitydb_sqlalchemy.types.TBool

9

Page 14: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

10 Chapter 2. Operators

Page 15: MobilityDB SQLAlchemy

CHAPTER

THREE

INSTALLATION

pip install mobilitydb_sqlalchemy

For getting started with MobilityDB SQLAlchemy, read our Quickstart

11

Page 16: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

12 Chapter 3. Installation

Page 17: MobilityDB SQLAlchemy

CHAPTER

FOUR

INDICES AND TABLES

• genindex

• modindex

• search

13

Page 18: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

14 Chapter 4. Indices and tables

Page 19: MobilityDB SQLAlchemy

PYTHON MODULE INDEX

mmobilitydb_sqlalchemy.comparator, 7

15

Page 20: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

16 Python Module Index

Page 21: MobilityDB SQLAlchemy

INDEX

Aalways_different_from() (mobili-

tydb_sqlalchemy.comparator.Comparatormethod), 7

always_equal_to() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 7

always_greater_than() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 7

always_greater_than_or_equal_to() (mo-bilitydb_sqlalchemy.comparator.Comparatormethod), 7

always_less_than() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 7

always_less_than_or_equal_to() (mobil-itydb_sqlalchemy.comparator.Comparatormethod), 7

Bbbox_always_after() (mobili-

tydb_sqlalchemy.comparator.Comparatormethod), 7

bbox_always_before() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 7

bbox_always_strictly_greater_than()(mobilitydb_sqlalchemy.comparator.Comparatormethod), 7

bbox_always_strictly_less_than() (mo-bilitydb_sqlalchemy.comparator.Comparatormethod), 7

bbox_contained() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 7

bbox_contains() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 7

bbox_does_not_extend_above() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 7

bbox_does_not_extend_below() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_does_not_extend_in_back() (mobil-itydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_does_not_extend_in_front() (mobil-itydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_does_not_extend_to_left() (mobil-itydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_does_not_extend_to_right() (mobil-itydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_never_after() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_never_before() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_never_greater_than() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_never_less_than() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_strictly_above() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_strictly_below() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_strictly_in_back() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_strictly_in_front() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bbox_strictly_to_left() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

17

Page 22: MobilityDB SQLAlchemy

MobilityDB SQLAlchemy, Release 0.4

bbox_strictly_to_right() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bboxes_equal() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

bboxes_overlap() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

CComparator (class in mobili-

tydb_sqlalchemy.comparator), 7

Ddistance() (mobili-

tydb_sqlalchemy.comparator.Comparatormethod), 8

Eever_different_from() (mobili-

tydb_sqlalchemy.comparator.Comparatormethod), 8

ever_equal_to() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 8

ever_greater_than() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 9

ever_greater_than_or_equal_to() (mobil-itydb_sqlalchemy.comparator.Comparatormethod), 9

ever_less_than() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 9

ever_less_than_or_equal_to() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 9

expr (mobilitydb_sqlalchemy.comparator.Comparatorattribute), 9

Mmobilitydb_sqlalchemy.comparator (mod-

ule), 7

Ssmallest_distance_ever_between() (mo-

bilitydb_sqlalchemy.comparator.Comparatormethod), 9

Ttemporal_equal() (mobili-

tydb_sqlalchemy.comparator.Comparatormethod), 9

temporal_greater_than() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 9

temporal_greater_than_or_equal_to()(mobilitydb_sqlalchemy.comparator.Comparatormethod), 9

temporal_less_than() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 9

temporal_less_than_or_equal_to() (mo-bilitydb_sqlalchemy.comparator.Comparatormethod), 9

temporal_not_equal() (mobili-tydb_sqlalchemy.comparator.Comparatormethod), 9

type (mobilitydb_sqlalchemy.comparator.Comparatorattribute), 9

18 Index