get_query_results works correctly. relationships between models changed

This commit is contained in:
DmitryGantimurov 2023-08-07 22:27:23 +03:00
parent dfe1f90748
commit f15c17a17e
8 changed files with 135 additions and 80 deletions

View File

@ -18,18 +18,18 @@ engine = create_engine(
SessionLocal = sessionmaker(bind=engine, autoflush=True, autocommit=False) SessionLocal = sessionmaker(bind=engine, autoflush=True, autocommit=False)
database = SessionLocal() database = SessionLocal()
# Base = declarative_base() Base = declarative_base()
# add your model's MetaData object here # # add your model's MetaData object here
# for 'autogenerate' support # # for 'autogenerate' support
# in your application's model: # # in your application's model:
class Base(DeclarativeBase): # class Base(DeclarativeBase):
metadata = MetaData(naming_convention={ # metadata = MetaData(naming_convention={
"ix": "ix_%(column_0_label)s", # "ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s", # "uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_`%(constraint_name)s`", # "ck": "ck_%(table_name)s_`%(constraint_name)s`",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", # "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s" # "pk": "pk_%(table_name)s"
}) # })

View File

@ -7,12 +7,13 @@ from fastapi.templating import Jinja2Templates
from fastapi.requests import Request from fastapi.requests import Request
from pydantic import json from pydantic import json
from typing import Any, Annotated, List from typing import Any, Annotated, List, Union
from starlette.staticfiles import StaticFiles from starlette.staticfiles import StaticFiles
import requests import requests
from uuid import uuid4 from uuid import uuid4
import random import random
import datetime
import ast import ast
import pathlib import pathlib
@ -20,7 +21,8 @@ import shutil
import os import os
from .db import Base, engine, SessionLocal, database from .db import Base, engine, SessionLocal, database
from .service import add_poems_to_db, generate_poem, check_obsolete from .service import add_poems_to_db, generate_poem, check_obsolete, get_query_results
from .scheduler import app as app_rocketry
from . import schemas, models, utils from . import schemas, models, utils
Base.metadata.create_all(bind=engine) Base.metadata.create_all(bind=engine)
@ -38,17 +40,23 @@ app.mount("/uploads", StaticFiles(directory = "./uploads"))
# add_poems_to_db(database) # add_poems_to_db(database)
@app.get("/api/announcements")#адрес объявлений # Каждый день в 00.00 проверяем все объявления (сравниваем текущую дату и срок годности)
def annoncements_list(owner_id: int = None, metro: str = None, category: str = None, booked_by: int = 0): # session_rocketry = app_rocketry.session
@app.get("/api/announcements", response_model=List[schemas.Announcement])#адрес объявлений
def annoncements_list(obsolete: Union[bool, None] = False, user_id: Union[int, None] = None, metro: Union[str, None] = None,
category: Union[str, None] = None):
# Считываем данные из Body и отображаем их на странице. # Считываем данные из Body и отображаем их на странице.
# В последствии будем вставлять данные в html-форму # В последствии будем вставлять данные в html-форму
params_to_sort = schemas.SortAnnouncements(obsolete=obsolete, user_id=user_id, metro=metro, category=category)
# Фильтруем по сроку годности # Фильтруем по сроку годности
not_expired = check_obsolete(current_date=datetime.date.today()) # not_expired = check_obsolete(current_date=datetime.date.today())
# Фильтруем по другим параметрам и делаем пересечение с not_expired # Фильтруем по другим параметрам и делаем пересечение с not_expired
result = not_expired.intersect(get_query_results(params_to_sort)) # result = not_expired.intersect(get_query_results(params_to_sort))
result = get_query_results(db=database, schema=params_to_sort)
return {"Success" : True, "list_of_announcements": result} return result
@app.get("/api/announcement")#адрес объявления @app.get("/api/announcement")#адрес объявления
@ -68,7 +76,7 @@ def single_annoncement(user_id:int):
# Занести объявление в базу данных # Занести объявление в базу данных
@app.put("/api/announcement")#адрес объявлений @app.put("/api/announcement")#адрес объявлений
def put_in_db(name: Annotated[str, Form()], category: Annotated[str, Form()], bestBy: Annotated[int, Form()], def put_in_db(name: Annotated[str, Form()], category: Annotated[str, Form()], bestBy: Annotated[datetime.date, Form()],
address: Annotated[str, Form()], longtitude: Annotated[float, Form()], latitude: Annotated[float, Form()], address: Annotated[str, Form()], longtitude: Annotated[float, Form()], latitude: Annotated[float, Form()],
description: Annotated[str, Form()], src: UploadFile, metro: Annotated[str, Form()], description: Annotated[str, Form()], src: UploadFile, metro: Annotated[str, Form()],
trashId: Annotated[int, Form()] = None): trashId: Annotated[int, Form()] = None):
@ -167,12 +175,14 @@ async def read_own_items(
# начисляем баллы пользователю # начисляем баллы пользователю
@app.post("/api/user/rating") @app.post("/api/user/rating")
def add_points(data: schemas.AddPoints): def add_points(data: schemas.AddPoints, current_user: Annotated[schemas.User, Depends(utils.get_current_user)]):
user = utils.get_user(data.user_id) if current_user.id != data.user_id:
if not user: user = utils.get_user(data.user_id)
raise HTTPException(status_code=404, detail="Item not found") if not user:
user.rating += data.rate raise HTTPException(status_code=404, detail="Item not found")
return {"Success": True} user.num_of_ratings += 1
user.rating = (user.rating + data.rate)/user.num_of_ratings
return {"Success": True}
# получаем данные о баллах пользователя # получаем данные о баллах пользователя

View File

@ -24,15 +24,16 @@ class User(Base):#класс пользователя
surname = Column(String)#фамилия пользователя surname = Column(String)#фамилия пользователя
disabled = Column(Boolean, default=False) disabled = Column(Boolean, default=False)
rating = Column(Integer, default=0) #баллы пользователя rating = Column(Integer, default=0) #баллы пользователя
num_of_ratings = Column(Integer, default=0) # количество оценок (т.е. то, сколько раз другие пользователи оценили текущего)
reg_date = Column(Date) # дата регистрации reg_date = Column(Date) # дата регистрации
items = relationship("Announcement", back_populates="users") announcements = relationship("Announcement", back_populates="user")
class Announcement(Base): #класс объявления class Announcement(Base): #класс объявления
__tablename__ = "announcements" __tablename__ = "announcements"
id = Column(Integer, primary_key=True, index=True) # айди объявления id = Column(Integer, primary_key=True, index=True) # айди объявления
user_id = Column(Integer, ForeignKey("users.id", name="fk_users_id")) # айди создателя объявления user_id = Column(Integer, ForeignKey("users.id")) # айди создателя объявления
name = Column(String) # название объявления name = Column(String) # название объявления
category = Column(String) #категория продукта из объявления category = Column(String) #категория продукта из объявления
best_by = Column(Date) #срок годности продукта из объявления best_by = Column(Date) #срок годности продукта из объявления
@ -47,7 +48,7 @@ class Announcement(Base): #класс объявления
# state = Column(Enum(State), default=State.published) # состояние объявления (опубликовано, забронировано, устарело) # state = Column(Enum(State), default=State.published) # состояние объявления (опубликовано, забронировано, устарело)
obsolete = Column(Boolean, default=False) # состояние объявления (по-умолчанию считаем его актуальным) obsolete = Column(Boolean, default=False) # состояние объявления (по-умолчанию считаем его актуальным)
owner = relationship("User", back_populates="items") user = relationship("User", back_populates="announcements")
class Trashbox(Base): #класс мусорных баков class Trashbox(Base): #класс мусорных баков

13
back/scheduler.py Normal file
View File

@ -0,0 +1,13 @@
from . import service
from rocketry import Rocketry
from rocketry.conds import daily
import datetime
app = Rocketry()
# Create some tasks:
@app.task("daily")
def daily_check():
service.check_obsolete(current_date=datetime.date.today())

View File

@ -26,6 +26,10 @@ class Announcement(BaseModel):
trashId: Union[int, None] = None trashId: Union[int, None] = None
booked_by: int #статус бронирования (либо -1, либо айди бронирующего) booked_by: int #статус бронирования (либо -1, либо айди бронирующего)
class Config:
orm_mode = True
arbitrary_types_allowed=True
class Token(BaseModel): class Token(BaseModel):
access_token: str access_token: str
@ -73,7 +77,7 @@ class DisposeRequest(BaseModel):
trashbox: TrashboxRequest trashbox: TrashboxRequest
class SortAnnouncements(BaseModel): class SortAnnouncements(BaseModel):
expired: Union[int, None] = False obsolete: Union[int, None] = False
user_id: Union[int, None] = None user_id: Union[int, None] = None
metro: Union[str, None] = None metro: Union[str, None] = None
category: Union[str, None] = None category: Union[str, None] = None

View File

@ -41,12 +41,12 @@ def add_poems_to_db(db: Session):
f1.close() f1.close()
# def generate_poem(db: Session): def generate_poem(db: Session):
# # генерируем 1 случайное id и выбираем объект бд с этим id # генерируем 1 случайное id и выбираем объект бд с этим id
# rand_id = random.randint(1, 102) rand_id = random.randint(1, 102)
# poem = db.query(models.Poems).filter(models.Poems.id == rand_id).first() poem = db.query(models.Poems).filter(models.Poems.id == rand_id).first()
# # возвращаем название и текст стихотворения # возвращаем название и текст стихотворения
# return {"name": poem.title, "text": poem.poem_text, "author":""} # добавить поле author в Poems return {"name": poem.title, "text": poem.poem_text, "author":""} # добавить поле author в Poems
#Вова тестирует получение поэм, Димоны, помогите пж #Вова тестирует получение поэм, Димоны, помогите пж
# def poems_to_front(db: Annotated[Session, Depends(utils.get_db)]): # def poems_to_front(db: Annotated[Session, Depends(utils.get_db)]):
# kolvo_stixov = 109 # пока количество стихотворений = 101 # kolvo_stixov = 109 # пока количество стихотворений = 101
@ -58,7 +58,7 @@ def add_poems_to_db(db: Session):
def get_query_results(db: Annotated[Session, Depends(utils.get_db)], schema: schemas.SortAnnouncements): def get_query_results(schema: schemas.SortAnnouncements, db: Annotated[Session, Depends(utils.get_db)]):
"""Функция для последовательного применения различных фильтров (через схему SortAnnouncements)""" """Функция для последовательного применения различных фильтров (через схему SortAnnouncements)"""
res = db.query(models.Announcement) res = db.query(models.Announcement)
fields = schema.__dict__ # параметры передоваемой схемы SortAnnouncements (ключи и значения) fields = schema.__dict__ # параметры передоваемой схемы SortAnnouncements (ключи и значения)
@ -71,16 +71,13 @@ def get_query_results(db: Annotated[Session, Depends(utils.get_db)], schema: sch
def check_obsolete(db: Annotated[Session, Depends(utils.get_db)], current_date: datetime.date): def check_obsolete(db: Annotated[Session, Depends(utils.get_db)], current_date: datetime.date):
""" """
Возвращаем список объектов базы данных типа Announcement Обновляем поле obsolete у всех объявлений раз в сутки
, удовлетворяющих условию obsolete == True
""" """
list_to_return = [] announcements = db.query(models.Announcement).all()
not_obsolete = database.query(models.Announcement).filter(models.Announcement.obsolete == True).all() for ann in announcements:
for ann in not_obsolete:
if ann.best_by < current_date: if ann.best_by < current_date:
ann.obsolete = False ann.obsolete = False
else: else:
list_to_return.append(ann) ann.obsolete = True
return list_to_return

View File

@ -0,0 +1,64 @@
"""User model got a new field: num_of_ratings; delete name of ForeignKey; relationships changed
Revision ID: 9c19b9658512
Revises: 4e4d30fd58fc
Create Date: 2023-08-07 18:16:32.386940
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '9c19b9658512'
down_revision = '4e4d30fd58fc'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('_alembic_tmp_users')
with op.batch_alter_table('announcements', schema=None) as batch_op:
batch_op.add_column(sa.Column('obsolete', sa.Boolean(), nullable=True))
batch_op.drop_column('state')
with op.batch_alter_table('poems', schema=None) as batch_op:
batch_op.add_column(sa.Column('title', sa.String(), nullable=True))
batch_op.add_column(sa.Column('text', sa.String(), nullable=True))
batch_op.add_column(sa.Column('author', sa.String(), nullable=True))
batch_op.drop_column('poem_text')
batch_op.drop_column('poem_name')
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.add_column(sa.Column('num_of_ratings', sa.Integer(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.drop_column('num_of_ratings')
with op.batch_alter_table('poems', schema=None) as batch_op:
batch_op.add_column(sa.Column('poem_name', sa.VARCHAR(), nullable=True))
batch_op.add_column(sa.Column('poem_text', sa.VARCHAR(), nullable=True))
batch_op.drop_column('author')
batch_op.drop_column('text')
batch_op.drop_column('title')
with op.batch_alter_table('announcements', schema=None) as batch_op:
batch_op.add_column(sa.Column('state', sa.VARCHAR(length=9), nullable=True))
batch_op.drop_column('obsolete')
op.create_table('_alembic_tmp_users',
sa.Column('id', sa.INTEGER(), nullable=False),
sa.Column('email', sa.VARCHAR(), nullable=True),
sa.Column('hashed_password', sa.VARCHAR(), nullable=True),
sa.Column('name', sa.VARCHAR(), nullable=True),
sa.Column('surname', sa.VARCHAR(), nullable=True),
sa.Column('disabled', sa.BOOLEAN(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###

View File

@ -1,34 +0,0 @@
"""state(enum) -> obsolete(Boolean)
Revision ID: faecbd04e5eb
Revises: 4e4d30fd58fc
Create Date: 2023-08-05 23:57:31.784676
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'faecbd04e5eb'
down_revision = '4e4d30fd58fc'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('announcements', schema=None) as batch_op:
batch_op.add_column(sa.Column('obsolete', sa.Boolean(), nullable=True))
batch_op.drop_column('state')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('announcements', schema=None) as batch_op:
batch_op.add_column(sa.Column('state', sa.VARCHAR(length=9), nullable=True))
batch_op.drop_column('obsolete')
# ### end Alembic commands ###