Implementing db querying
This commit is contained in:
85
back/db.py
Normal file
85
back/db.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
from sqlalchemy import Column, Table, Integer, MetaData, String, select, create_engine
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
|
|
||||||
|
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
|
||||||
|
|
||||||
|
engine = create_engine(
|
||||||
|
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
||||||
|
)
|
||||||
|
|
||||||
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||||
|
|
||||||
|
|
||||||
|
def get_db():
|
||||||
|
db = SessionLocal()
|
||||||
|
try:
|
||||||
|
yield db
|
||||||
|
finally:
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
class People(Base):
|
||||||
|
__tablename__ = "people"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True, index=True)
|
||||||
|
name = Column(String)
|
||||||
|
age = Column(Integer)
|
||||||
|
gender = Column(String)
|
||||||
|
country = Column(String)
|
||||||
|
|
||||||
|
|
||||||
|
def create_people_from_list(db, people_list):
|
||||||
|
count = 0
|
||||||
|
for p in people_list:
|
||||||
|
db_people = People(**p.dict())
|
||||||
|
db.add(db_people)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
def get_average_age_by_country(db) -> []:
|
||||||
|
return db.query(People.country.label('country'), func.avg(People.age).label('average_age'))\
|
||||||
|
.group_by( People.country).all()
|
||||||
|
|
||||||
|
|
||||||
|
def count_people_by_country(db) -> []:
|
||||||
|
return db.query(People.country.label('country'), func.count(People.id).label('people_count'))\
|
||||||
|
.group_by( People.country).all()
|
||||||
|
|
||||||
|
|
||||||
|
def get_gender_repartition_by_country(db, country) -> []:
|
||||||
|
count_women, total = db.query(
|
||||||
|
|
||||||
|
select(func.count(People.id).label('count_women')) \
|
||||||
|
.where(People.gender == 'F') \
|
||||||
|
.where(People.country == country).subquery(),
|
||||||
|
|
||||||
|
select(func.count(People.id).label('total')) \
|
||||||
|
.where(People.country == country).subquery(),
|
||||||
|
|
||||||
|
).first()
|
||||||
|
female_proportion = count_women / total
|
||||||
|
return {
|
||||||
|
"female_proportion": female_proportion,
|
||||||
|
"male_proportion": 1 - female_proportion
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
meta = MetaData()
|
||||||
|
Table(
|
||||||
|
'people', meta,
|
||||||
|
Column('id', Integer, primary_key=True),
|
||||||
|
Column('name', String),
|
||||||
|
Column('age', Integer),
|
||||||
|
Column('gender', String),
|
||||||
|
Column('country', String),
|
||||||
|
)
|
||||||
|
meta.create_all(engine)
|
||||||
39
main.py
39
main.py
@@ -1,43 +1,36 @@
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI, Depends
|
||||||
|
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from back.schemas import PeopleList, AverageAgeByCountry, CountByCountry, GenderRepartition
|
from back.schemas import PeopleList, AverageAgeByCountry, CountByCountry, GenderRepartition
|
||||||
|
from back.db import get_db, create_people_from_list, get_average_age_by_country, \
|
||||||
|
count_people_by_country, get_gender_repartition_by_country
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
@app.post("/people")
|
@app.post("/people")
|
||||||
async def create_people(people_list: PeopleList) -> dict:
|
async def create_people(people_list: PeopleList, db: Session = Depends(get_db)) -> dict:
|
||||||
|
count = create_people_from_list(db, people_list.people)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"message": "People list has been succesfully imported",
|
"message": "People list has been succesfully imported",
|
||||||
"records_created": 10
|
"records_created": count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/average_age", response_model=List[AverageAgeByCountry])
|
@app.get("/average_age", response_model=List[AverageAgeByCountry])
|
||||||
async def read_average_age() -> List[AverageAgeByCountry]:
|
async def read_average_age(db: Session = Depends(get_db)) -> List[AverageAgeByCountry]:
|
||||||
return [
|
return [AverageAgeByCountry(**a) for a in get_average_age_by_country(db)]
|
||||||
{'country': 'FR', 'average_age': 15.0},
|
|
||||||
{'country': 'BE', 'average_age': 25.0},
|
|
||||||
{'country': 'DE', 'average_age': 23.3},
|
|
||||||
{'country': 'IT', 'average_age': 45.0},
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/count_by_country", response_model=List[CountByCountry])
|
@app.get("/count_by_country", response_model=List[CountByCountry])
|
||||||
async def read_count_by_country() -> List[CountByCountry]:
|
async def read_count_by_country(db: Session = Depends(get_db)) -> List[CountByCountry]:
|
||||||
return [
|
return [CountByCountry(**a) for a in count_people_by_country(db)]
|
||||||
{'country': 'FR', 'people_count': 2},
|
|
||||||
{'country': 'BE', 'people_count': 4},
|
|
||||||
{'country': 'DE', 'people_count': 3},
|
|
||||||
{'country': 'IT', 'people_count': 1},
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/gender_repartition/{country}", response_model=GenderRepartition)
|
@app.get("/gender_repartition/{country}", response_model=GenderRepartition)
|
||||||
async def read_count_by_gender(country: str) -> GenderRepartition:
|
async def read_count_by_gender(country: str, db: Session = Depends(get_db)) -> GenderRepartition:
|
||||||
return {
|
return GenderRepartition(**get_gender_repartition_by_country(db, country))
|
||||||
"female_proportion": 33.3,
|
|
||||||
"male_proportion": 66.6
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user