Rest api, CRUD for wind_parks

This commit is contained in:
Danil_Malin 2024-11-05 20:53:55 +04:00
parent 484f1f205e
commit 1fd0f946e6
6 changed files with 139 additions and 29 deletions

View File

@ -1,11 +1,20 @@
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker, declarative_base, Session
# TODO Maybe create env file # TODO Maybe create env file
DATABASE_URL = "mysql+pymysql://wind:wind@193.124.203.110:3306/wind_towers" DATABASE_URL = "mysql+pymysql://wind:wind@193.124.203.110:3306/wind_towers"
engine = create_engine(DATABASE_URL) engine = create_engine(DATABASE_URL)
session_maker = sessionmaker(autocommit=False, autoflush=False, bind=engine) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Базовый класс для декларативных моделей
Base = declarative_base()
# Функция для получения сессии
def get_db() -> Session:
db = SessionLocal()
try:
yield db
finally:
db.close()

View File

@ -1,6 +1,6 @@
from datetime import datetime from datetime import datetime
from sqlalchemy import Integer, ForeignKey, String from sqlalchemy import Integer, ForeignKey, String, Float
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, relationship from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, relationship
from sqlalchemy.dialects.mysql import TIMESTAMP, TIME, VARCHAR from sqlalchemy.dialects.mysql import TIMESTAMP, TIME, VARCHAR
@ -28,39 +28,46 @@ class Weather(Base):
RainStorm: Mapped[float] RainStorm: Mapped[float]
RainYear: Mapped[float] RainYear: Mapped[float]
SunRise: Mapped[datetime] = mapped_column(TIME) SunRise: Mapped[datetime] = mapped_column(TIME)
SunSet:Mapped[datetime] = mapped_column(TIME) SunSet: Mapped[datetime] = mapped_column(TIME)
TempIn: Mapped[float] TempIn: Mapped[float]
TempOut: Mapped[float] TempOut: Mapped[float]
WindDir: Mapped[str] = mapped_column(VARCHAR(50)) WindDir: Mapped[str] = mapped_column(VARCHAR(50))
WindSpeed: Mapped[float] WindSpeed: Mapped[float]
WindSpeed10Min: Mapped[float] WindSpeed10Min: Mapped[float]
class WindTurbineType(Base): class WindTurbineType(Base):
__tablename__ = 'wind_turbine_type' __tablename__ = 'wind_turbine_type'
Id: Mapped[int] = mapped_column(primary_key=True) Id: Mapped[int] = mapped_column(primary_key=True)
Name: Mapped[str] = mapped_column(VARCHAR(255)) Name: Mapped[str] = mapped_column(VARCHAR(255))
Height: Mapped[float] Height: Mapped[float] = mapped_column(Float)
BladeLength: Mapped[float] BladeLength: Mapped[float] = mapped_column(Float)
# Связь с WindParkTurbine
turbine_parks: Mapped["list[WindParkTurbine]"] = relationship("WindParkTurbine", back_populates="turbine")
class WindPark(Base): class WindPark(Base):
__tablename__ = 'wind_park' __tablename__ = 'wind_park'
Id: Mapped[int] = mapped_column(primary_key=True) Id: Mapped[int] = mapped_column(primary_key=True)
Name: Mapped[str] = mapped_column(VARCHAR(255)) Name: Mapped[str] = mapped_column(VARCHAR(255))
CenterLatitude: Mapped[float] CenterLatitude: Mapped[float] = mapped_column(Float)
CenterLongitude: Mapped[float] CenterLongitude: Mapped[float] = mapped_column(Float)
# Связь с WindParkTurbine
wind_park_turbines: Mapped["list[WindParkTurbine]"] = relationship("WindParkTurbine", back_populates="wind_park")
class WindParkTurbine(Base): class WindParkTurbine(Base):
__tablename__ = 'wind_park_turbine' __tablename__ = 'wind_park_turbine'
wind_park_id: Mapped[int] = mapped_column(Integer, ForeignKey('wind_park.id'), primary_key=True) wind_park_id: Mapped[int] = mapped_column(Integer, ForeignKey('wind_park.Id'), primary_key=True)
turbine_id: Mapped[int] = mapped_column(Integer, ForeignKey('wind_turbine_type.id'), primary_key=True) turbine_id: Mapped[int] = mapped_column(Integer, ForeignKey('wind_turbine_type.Id'), primary_key=True)
x_offset: Mapped[int] = mapped_column(Integer, nullable=False) x_offset: Mapped[int] = mapped_column(Integer, nullable=False)
y_offset: Mapped[int] = mapped_column(Integer, nullable=False) y_offset: Mapped[int] = mapped_column(Integer, nullable=False)
angle: Mapped[int] = mapped_column(Integer, nullable=True) angle: Mapped[int] = mapped_column(Integer, nullable=True)
comment: Mapped[str] = mapped_column(String(2000), nullable=True) comment: Mapped[str] = mapped_column(String(2000), nullable=True)
# Связи с другими таблицами # Связи с другими таблицами
wind_park: Mapped["WindPark"] = relationship("WindPark", back_populates="wind_park_turbines") wind_park: Mapped[WindPark] = relationship("WindPark", back_populates="wind_park_turbines")
turbine: Mapped["WindTurbineType"] = relationship("WindTurbineType", back_populates="turbine_parks") turbine: Mapped[WindTurbineType] = relationship("WindTurbineType", back_populates="turbine_parks")

View File

@ -1,9 +1,11 @@
from typing import List, Type
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from .models import WindTurbineType, WindPark, WindParkTurbine from .models import WindTurbineType, WindPark, WindParkTurbine
from .schemas import WindTurbineTypeCreate, WindParkCreate, WindParkTurbineCreate from .schemas import WindTurbineTypeCreate, WindParkCreate, WindParkTurbineCreate, WindParkResponse, WindTurbineResponse
from data.database import session_maker from data.database import SessionLocal
from data.models import Weather from data.models import Weather
from data.schemas import SWeatherInfo from data.schemas import SWeatherInfo
@ -11,7 +13,7 @@ from data.schemas import SWeatherInfo
class WeatherRepository: class WeatherRepository:
@classmethod @classmethod
def get_all(cls): def get_all(cls):
with session_maker() as session: with SessionLocal() as session:
query = ( query = (
select(Weather) select(Weather)
) )
@ -21,7 +23,7 @@ class WeatherRepository:
@classmethod @classmethod
def get_by_id(cls, id): def get_by_id(cls, id):
with session_maker() as session: with SessionLocal() as session:
query = ( query = (
select(Weather).where(Weather.id == id) select(Weather).where(Weather.id == id)
) )
@ -64,6 +66,10 @@ class WindTurbineTypeRepository:
return True return True
return False return False
@staticmethod
def get_all_turbines(db: Session) -> list[Type[WindTurbineType]]:
return db.query(WindTurbineType).all()
class WindParkRepository: class WindParkRepository:
@staticmethod @staticmethod
@ -98,6 +104,26 @@ class WindParkRepository:
return True return True
return False return False
@staticmethod
def get_all_parks(db: Session) -> list[WindParkResponse]:
return db.query(WindPark).all()
@staticmethod
def get_turbines_by_park_id(park_id: int, db: Session) -> list[WindTurbineResponse]:
turbines = (
db.query(WindParkTurbine)
.filter(WindParkTurbine.wind_park_id == park_id)
.all()
)
if not turbines:
return [] # Возвращаем пустой список, если не найдено
turbine_ids = [turbine.turbine_id for turbine in turbines]
turbine_details = db.query(WindTurbineType).filter(WindTurbineType.Id.in_(turbine_ids)).all()
return turbine_details
class WindParkTurbineRepository: class WindParkTurbineRepository:
@staticmethod @staticmethod
@ -130,4 +156,4 @@ class WindParkTurbineRepository:
db.delete(db_park_turbine) db.delete(db_park_turbine)
db.commit() db.commit()
return True return True
return False return False

View File

@ -28,9 +28,11 @@ class WindTurbineTypeBase(BaseModel):
Height: float Height: float
BladeLength: float BladeLength: float
class WindTurbineTypeCreate(WindTurbineTypeBase): class WindTurbineTypeCreate(WindTurbineTypeBase):
pass pass
class WindTurbineTypeResponse(WindTurbineTypeBase): class WindTurbineTypeResponse(WindTurbineTypeBase):
Id: int Id: int
@ -43,15 +45,10 @@ class WindParkBase(BaseModel):
CenterLatitude: float CenterLatitude: float
CenterLongitude: float CenterLongitude: float
class WindParkCreate(WindParkBase): class WindParkCreate(WindParkBase):
pass pass
class WindParkResponse(WindParkBase):
Id: int
class Config:
orm_mode = True
class WindParkTurbineBase(BaseModel): class WindParkTurbineBase(BaseModel):
wind_park_id: int wind_park_id: int
@ -61,9 +58,41 @@ class WindParkTurbineBase(BaseModel):
angle: Optional[int] = None angle: Optional[int] = None
comment: Optional[str] = None comment: Optional[str] = None
class WindParkTurbineCreate(WindParkTurbineBase): class WindParkTurbineCreate(WindParkTurbineBase):
pass pass
class WindParkTurbineResponse(WindParkTurbineBase): class WindParkTurbineResponse(WindParkTurbineBase):
class Config: class Config:
orm_mode = True orm_mode = True
class WindTurbineType(BaseModel):
Id: int
Name: str
Height: float
BladeLength: float
class Config:
orm_mode = True
class WindParkResponse(BaseModel):
Id: int
Name: str
CenterLatitude: float
CenterLongitude: float
class Config:
orm_mode = True
class WindTurbineResponse(BaseModel):
Id: int
Name: str
Height: float
BladeLength: float
class Config:
orm_mode = True

View File

@ -6,6 +6,7 @@ from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from routers.wind_park_router import router as wind_park_router
from routers.floris_router import router as floris_router from routers.floris_router import router as floris_router
from routers.floris_template_router import router as floris_template_router from routers.floris_template_router import router as floris_template_router
from routers.weather_router import router as weather_router from routers.weather_router import router as weather_router
@ -33,3 +34,4 @@ app.mount("/public", StaticFiles(directory=Path("../public")), name="public")
app.include_router(floris_router) app.include_router(floris_router)
app.include_router(floris_template_router) app.include_router(floris_template_router)
app.include_router(weather_router) app.include_router(weather_router)
app.include_router(wind_park_router)

View File

@ -1,8 +1,8 @@
from fastapi import APIRouter, HTTPException, Depends from fastapi import APIRouter, HTTPException, Depends
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from typing import List
from data.schemas import WindTurbineTypeCreate, WindTurbineTypeResponse, WindParkCreate, WindParkResponse, WindParkTurbineCreate, WindParkTurbineResponse from data.schemas import WindTurbineTypeCreate, WindTurbineTypeResponse, WindParkCreate, WindParkResponse, \
WindParkTurbineCreate, WindParkTurbineResponse, WindTurbineResponse
from data.database import get_db from data.database import get_db
from data.repository import WindTurbineTypeRepository, WindParkRepository, WindParkTurbineRepository from data.repository import WindTurbineTypeRepository, WindParkRepository, WindParkTurbineRepository
@ -11,11 +11,13 @@ router = APIRouter(
tags=["Wind API"], tags=["Wind API"],
) )
# Wind Turbine Type CRUD # Wind Turbine Type CRUD
@router.post("/turbine_type/", response_model=WindTurbineTypeResponse) @router.post("/turbine_type/", response_model=WindTurbineTypeResponse)
async def create_turbine_type(turbine_type: WindTurbineTypeCreate, db: Session = Depends(get_db)): async def create_turbine_type(turbine_type: WindTurbineTypeCreate, db: Session = Depends(get_db)):
return WindTurbineTypeRepository.create(db=db, turbine_type=turbine_type) return WindTurbineTypeRepository.create(db=db, turbine_type=turbine_type)
@router.get("/turbine_type/{turbine_type_id}", response_model=WindTurbineTypeResponse) @router.get("/turbine_type/{turbine_type_id}", response_model=WindTurbineTypeResponse)
async def read_turbine_type(turbine_type_id: int, db: Session = Depends(get_db)): async def read_turbine_type(turbine_type_id: int, db: Session = Depends(get_db)):
turbine_type = WindTurbineTypeRepository.get(db=db, turbine_type_id=turbine_type_id) turbine_type = WindTurbineTypeRepository.get(db=db, turbine_type_id=turbine_type_id)
@ -23,24 +25,29 @@ async def read_turbine_type(turbine_type_id: int, db: Session = Depends(get_db))
raise HTTPException(status_code=404, detail="Turbine Type not found") raise HTTPException(status_code=404, detail="Turbine Type not found")
return turbine_type return turbine_type
@router.put("/turbine_type/{turbine_type_id}", response_model=WindTurbineTypeResponse) @router.put("/turbine_type/{turbine_type_id}", response_model=WindTurbineTypeResponse)
async def update_turbine_type(turbine_type_id: int, turbine_type: WindTurbineTypeCreate, db: Session = Depends(get_db)): async def update_turbine_type(turbine_type_id: int, turbine_type: WindTurbineTypeCreate, db: Session = Depends(get_db)):
updated_turbine_type = WindTurbineTypeRepository.update(db=db, turbine_type_id=turbine_type_id, turbine_type=turbine_type) updated_turbine_type = WindTurbineTypeRepository.update(db=db, turbine_type_id=turbine_type_id,
turbine_type=turbine_type)
if updated_turbine_type is None: if updated_turbine_type is None:
raise HTTPException(status_code=404, detail="Turbine Type not found") raise HTTPException(status_code=404, detail="Turbine Type not found")
return updated_turbine_type return updated_turbine_type
@router.delete("/turbine_type/{turbine_type_id}", status_code=204) @router.delete("/turbine_type/{turbine_type_id}", status_code=204)
async def delete_turbine_type(turbine_type_id: int, db: Session = Depends(get_db)): async def delete_turbine_type(turbine_type_id: int, db: Session = Depends(get_db)):
result = WindTurbineTypeRepository.delete(db=db, turbine_type_id=turbine_type_id) result = WindTurbineTypeRepository.delete(db=db, turbine_type_id=turbine_type_id)
if not result: if not result:
raise HTTPException(status_code=404, detail="Turbine Type not found") raise HTTPException(status_code=404, detail="Turbine Type not found")
# Wind Park CRUD # Wind Park CRUD
@router.post("/park/", response_model=WindParkResponse) @router.post("/park/", response_model=WindParkResponse)
async def create_park(park: WindParkCreate, db: Session = Depends(get_db)): async def create_park(park: WindParkCreate, db: Session = Depends(get_db)):
return WindParkRepository.create(db=db, park=park) return WindParkRepository.create(db=db, park=park)
@router.get("/park/{park_id}", response_model=WindParkResponse) @router.get("/park/{park_id}", response_model=WindParkResponse)
async def read_park(park_id: int, db: Session = Depends(get_db)): async def read_park(park_id: int, db: Session = Depends(get_db)):
park = WindParkRepository.get(db=db, park_id=park_id) park = WindParkRepository.get(db=db, park_id=park_id)
@ -48,6 +55,7 @@ async def read_park(park_id: int, db: Session = Depends(get_db)):
raise HTTPException(status_code=404, detail="Park not found") raise HTTPException(status_code=404, detail="Park not found")
return park return park
@router.put("/park/{park_id}", response_model=WindParkResponse) @router.put("/park/{park_id}", response_model=WindParkResponse)
async def update_park(park_id: int, park: WindParkCreate, db: Session = Depends(get_db)): async def update_park(park_id: int, park: WindParkCreate, db: Session = Depends(get_db)):
updated_park = WindParkRepository.update(db=db, park_id=park_id, park=park) updated_park = WindParkRepository.update(db=db, park_id=park_id, park=park)
@ -55,17 +63,20 @@ async def update_park(park_id: int, park: WindParkCreate, db: Session = Depends(
raise HTTPException(status_code=404, detail="Park not found") raise HTTPException(status_code=404, detail="Park not found")
return updated_park return updated_park
@router.delete("/park/{park_id}", status_code=204) @router.delete("/park/{park_id}", status_code=204)
async def delete_park(park_id: int, db: Session = Depends(get_db)): async def delete_park(park_id: int, db: Session = Depends(get_db)):
result = WindParkRepository.delete(db=db, park_id=park_id) result = WindParkRepository.delete(db=db, park_id=park_id)
if not result: if not result:
raise HTTPException(status_code=404, detail="Park not found") raise HTTPException(status_code=404, detail="Park not found")
# Wind Park Turbine CRUD # Wind Park Turbine CRUD
@router.post("/park_turbine/", response_model=WindParkTurbineResponse) @router.post("/park_turbine/", response_model=WindParkTurbineResponse)
async def create_park_turbine(park_turbine: WindParkTurbineCreate, db: Session = Depends(get_db)): async def create_park_turbine(park_turbine: WindParkTurbineCreate, db: Session = Depends(get_db)):
return WindParkTurbineRepository.create(db=db, park_turbine=park_turbine) return WindParkTurbineRepository.create(db=db, park_turbine=park_turbine)
@router.get("/park_turbine/{park_turbine_id}", response_model=WindParkTurbineResponse) @router.get("/park_turbine/{park_turbine_id}", response_model=WindParkTurbineResponse)
async def read_park_turbine(park_turbine_id: int, db: Session = Depends(get_db)): async def read_park_turbine(park_turbine_id: int, db: Session = Depends(get_db)):
park_turbine = WindParkTurbineRepository.get(db=db, park_turbine_id=park_turbine_id) park_turbine = WindParkTurbineRepository.get(db=db, park_turbine_id=park_turbine_id)
@ -73,15 +84,41 @@ async def read_park_turbine(park_turbine_id: int, db: Session = Depends(get_db))
raise HTTPException(status_code=404, detail="Park Turbine not found") raise HTTPException(status_code=404, detail="Park Turbine not found")
return park_turbine return park_turbine
@router.put("/park_turbine/{park_turbine_id}", response_model=WindParkTurbineResponse) @router.put("/park_turbine/{park_turbine_id}", response_model=WindParkTurbineResponse)
async def update_park_turbine(park_turbine_id: int, park_turbine: WindParkTurbineCreate, db: Session = Depends(get_db)): async def update_park_turbine(park_turbine_id: int, park_turbine: WindParkTurbineCreate, db: Session = Depends(get_db)):
updated_park_turbine = WindParkTurbineRepository.update(db=db, park_turbine_id=park_turbine_id, park_turbine=park_turbine) updated_park_turbine = WindParkTurbineRepository.update(db=db, park_turbine_id=park_turbine_id,
park_turbine=park_turbine)
if updated_park_turbine is None: if updated_park_turbine is None:
raise HTTPException(status_code=404, detail="Park Turbine not found") raise HTTPException(status_code=404, detail="Park Turbine not found")
return updated_park_turbine return updated_park_turbine
@router.delete("/park_turbine/{park_turbine_id}", status_code=204) @router.delete("/park_turbine/{park_turbine_id}", status_code=204)
async def delete_park_turbine(park_turbine_id: int, db: Session = Depends(get_db)): async def delete_park_turbine(park_turbine_id: int, db: Session = Depends(get_db)):
result = WindParkTurbineRepository.delete(db=db, park_turbine_id=park_turbine_id) result = WindParkTurbineRepository.delete(db=db, park_turbine_id=park_turbine_id)
if not result: if not result:
raise HTTPException(status_code=404, detail="Park Turbine not found") raise HTTPException(status_code=404, detail="Park Turbine not found")
@router.get("/parks/", response_model=list[WindParkResponse])
async def get_all_parks(db: Session = Depends(get_db)):
"""Получить все ветропарки"""
return WindParkRepository.get_all_parks(db)
@router.get("/parks/{park_id}/turbines/", response_model=list[WindTurbineResponse])
async def get_turbines_by_park_id(park_id: int, db: Session = Depends(get_db)):
"""Получить все турбины в ветропарке по ID"""
turbines = WindParkRepository.get_turbines_by_park_id(park_id, db)
if not turbines:
raise HTTPException(status_code=404, detail="Турбины не найдены для данного ветропарка")
return turbines
@router.get("/turbines/", response_model=list[WindTurbineResponse])
async def get_all_turbines(db: Session = Depends(get_db)):
"""Получить все турбины"""
return WindTurbineTypeRepository.get_all_turbines(db)