From 97cf413db4539f85244838df92fdebad00bac668 Mon Sep 17 00:00:00 2001 From: Robert Goldmann <deadlocker@gmx.de> Date: Sat, 16 Jan 2021 17:14:41 +0100 Subject: [PATCH] added database access and routes for measurements --- src/logic/databaseNew/Crud.py | 31 ++++++++++++++++++ src/logic/databaseNew/Models.py | 12 +++++++ src/logic/databaseNew/Schemas.py | 31 ++++++++++++------ src/main.py | 3 +- src/routers/MeasurementRouter.py | 54 ++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 src/routers/MeasurementRouter.py diff --git a/src/logic/databaseNew/Crud.py b/src/logic/databaseNew/Crud.py index 4fbe503..ae4f2d6 100644 --- a/src/logic/databaseNew/Crud.py +++ b/src/logic/databaseNew/Crud.py @@ -1,7 +1,11 @@ +from datetime import datetime + from sqlalchemy.orm import Session from logic.databaseNew import Models, Schemas +DATE_FORMAT = '%Y-%m-%d %H:%M:%S' + # ===== devices ===== @@ -57,3 +61,30 @@ def create_sensor(db: Session, sensor: Schemas.SensorCreate): def delete_sensor(db: Session, sensor: Schemas.Sensor): db.delete(sensor) db.commit() + + +# ===== measurements ===== + +def get_measurements(db: Session, skip: int = 0, limit: int = 100): + return db.query(Models.Measurement).offset(skip).limit(limit).all() + + +def get_measurement(db: Session, measurementId: int): + return db.query(Models.Measurement).filter(Models.Measurement.id == measurementId).first() + + +def create_measurement(db: Session, measurement: Schemas.MeasurementCreate): + dbMeasurement = Models.Measurement(**measurement.dict(), timestamp=__get_current_datetime()) + db.add(dbMeasurement) + db.commit() + db.refresh(dbMeasurement) + return dbMeasurement + + +def delete_measurement(db: Session, measurement: Schemas.Measurement): + db.delete(measurement) + db.commit() + + +def __get_current_datetime(): + return datetime.strftime(datetime.now(), DATE_FORMAT) diff --git a/src/logic/databaseNew/Models.py b/src/logic/databaseNew/Models.py index 8d73068..c6fb22b 100644 --- a/src/logic/databaseNew/Models.py +++ b/src/logic/databaseNew/Models.py @@ -22,3 +22,15 @@ class Sensor(Base): deviceId = Column(Integer, ForeignKey('device.id')) device = relationship('Device', back_populates='sensors') + measurements = relationship('Measurement', back_populates='sensor', cascade='all,delete') + + +class Measurement(Base): + __tablename__ = 'measurement' + + id = Column(Integer, primary_key=True, index=True) + timestamp = Column(String, index=True, nullable=False) + value = Column(String, index=True, nullable=False) + sensorId = Column(Integer, ForeignKey('sensor.id')) + + sensor = relationship('Sensor', back_populates='measurements') diff --git a/src/logic/databaseNew/Schemas.py b/src/logic/databaseNew/Schemas.py index 7d15943..711864f 100644 --- a/src/logic/databaseNew/Schemas.py +++ b/src/logic/databaseNew/Schemas.py @@ -7,6 +7,22 @@ class Status(BaseModel): message: str +# ===== measurement ===== +class Measurement(BaseModel): + id: int + value: str + timestamp: str + sensorId: int + + class Config: + orm_mode = True + + +class MeasurementCreate(BaseModel): + value: str + sensorId: int + + # ===== sensor ===== class SensorBase(BaseModel): id: int @@ -23,7 +39,7 @@ class SensorCreate(BaseModel): deviceId: int -class Sensor(BaseModel): +class Sensor(SensorBase): id: int name: str type: str @@ -34,17 +50,14 @@ class Sensor(BaseModel): # ===== device ===== -class DeviceBase(BaseModel): +class Device(BaseModel): id: int name: str - - -class DeviceCreate(BaseModel): - name: str - - -class Device(DeviceBase): sensors: List[SensorBase] class Config: orm_mode = True + + +class DeviceCreate(BaseModel): + name: str diff --git a/src/main.py b/src/main.py index 39099cf..0a98307 100644 --- a/src/main.py +++ b/src/main.py @@ -9,7 +9,7 @@ from Settings import SETTINGS from logic import Constants from logic.databaseNew import Models from logic.databaseNew.Database import engine -from routers import DeviceRouter, SensorRouter +from routers import DeviceRouter, SensorRouter, MeasurementRouter LOGGER = DefaultLogger().create_logger_if_not_exists(Constants.APP_NAME) @@ -25,6 +25,7 @@ app = FastAPI(title=Constants.APP_NAME, servers=[{'url': SETTINGS['api']['url'], 'description': f'{Constants.APP_NAME} API'}]) app.include_router(DeviceRouter.router) app.include_router(SensorRouter.router) +app.include_router(MeasurementRouter.router) @app.get('/') diff --git a/src/routers/MeasurementRouter.py b/src/routers/MeasurementRouter.py new file mode 100644 index 0000000..6b96151 --- /dev/null +++ b/src/routers/MeasurementRouter.py @@ -0,0 +1,54 @@ +from typing import List + +from fastapi import APIRouter, HTTPException, Depends +from sqlalchemy.orm import Session + +from Dependencies import get_database, check_api_key +from logic.databaseNew import Schemas, Crud +from logic.databaseNew.Schemas import Status + +router = APIRouter( + prefix='/measurement', + tags=['measurement'] +) + + +@router.get('/', response_model=List[Schemas.Measurement], + summary='Gets all measurements') +async def read_measurements(skip: int = 0, limit: int = 100, db: Session = Depends(get_database)): + return Crud.get_measurements(db, skip=skip, limit=limit) + + +@router.get('/{measurementId}', response_model=Schemas.Measurement, + summary='Gets a specific measurement', + responses={404: {'description': 'Measurement not found'}}) +async def read_measurement(measurementId: int, db: Session = Depends(get_database)): + measurement = Crud.get_measurement(db, measurementId=measurementId) + if measurement is None: + raise HTTPException(status_code=404, detail='Measurement not found') + return measurement + + +@router.post('/', response_model=Schemas.Measurement, + summary='Adds a new measurement', + responses={404: {'description': 'No sensor with id "{measurement.sensorId}" existing'}}, + dependencies=[Depends(check_api_key)]) +async def create_measurement(measurement: Schemas.MeasurementCreate, db: Session = Depends(get_database)): + existingSensor = Crud.get_sensor(db, measurement.sensorId) + if not existingSensor: + raise HTTPException(status_code=404, detail=f'No sensor with id "{measurement.sensorId}" existing') + + return Crud.create_measurement(db=db, measurement=measurement) + + +@router.delete('/{measurementId}', response_model=Status, + summary='Deletes a specific measurementId', + responses={404: {'description': 'Measurement not found'}}, + dependencies=[Depends(check_api_key)]) +async def delete_measurement(measurementId: int, db: Session = Depends(get_database)): + measurement = Crud.get_measurement(db, measurementId=measurementId) + if measurement is None: + raise HTTPException(status_code=404, detail='Measurement not found') + + Crud.delete_measurement(db, measurement) + return Status(message=f'Deleted measurement {measurement.id}') -- GitLab