create dataset comments

This commit is contained in:
Ivanov Matvey 2025-03-13 22:47:31 +10:00
parent 883e1d4359
commit 03c4941af0
9 changed files with 107 additions and 39 deletions

View File

@ -0,0 +1,32 @@
"""empty message
Revision ID: 7182f3a2d8f1
Revises: 9975c56b36b8
Create Date: 2025-03-13 22:02:24.302197
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '7182f3a2d8f1'
down_revision: Union[str, None] = '9975c56b36b8'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('post', sa.Column('blog_id', sa.INTEGER(), nullable=False))
op.create_foreign_key(None, 'post', 'blog', ['blog_id'], ['id'])
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, 'post', type_='foreignkey')
op.drop_column('post', 'blog_id')
# ### end Alembic commands ###

View File

@ -21,17 +21,6 @@ SET default_tablespace = '';
SET default_table_access_method = heap; SET default_table_access_method = heap;
--
-- Name: alembic_version; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.alembic_version (
version_num character varying(32) NOT NULL
);
ALTER TABLE public.alembic_version OWNER TO postgres;
-- --
-- Name: blog; Type: TABLE; Schema: public; Owner: postgres -- Name: blog; Type: TABLE; Schema: public; Owner: postgres
-- --
@ -76,7 +65,8 @@ CREATE TABLE public.post (
id integer NOT NULL, id integer NOT NULL,
header character varying NOT NULL, header character varying NOT NULL,
text character varying NOT NULL, text character varying NOT NULL,
author_id integer NOT NULL author_id integer NOT NULL,
blog_id integer NOT NULL
); );
@ -160,13 +150,6 @@ ALTER TABLE ONLY public.post ALTER COLUMN id SET DEFAULT nextval('public.post_id
ALTER TABLE ONLY public."user" ALTER COLUMN id SET DEFAULT nextval('public.user_id_seq'::regclass); ALTER TABLE ONLY public."user" ALTER COLUMN id SET DEFAULT nextval('public.user_id_seq'::regclass);
--
-- Data for Name: alembic_version; Type: TABLE DATA; Schema: public; Owner: postgres
--
INSERT INTO public.alembic_version (version_num) VALUES ('9975c56b36b8');
-- --
-- Data for Name: blog; Type: TABLE DATA; Schema: public; Owner: postgres -- Data for Name: blog; Type: TABLE DATA; Schema: public; Owner: postgres
-- --
@ -179,8 +162,8 @@ INSERT INTO public.blog (id, owner_id, name, description) VALUES (3, 2, 'мой
-- Data for Name: post; Type: TABLE DATA; Schema: public; Owner: postgres -- Data for Name: post; Type: TABLE DATA; Schema: public; Owner: postgres
-- --
INSERT INTO public.post (id, header, text, author_id) VALUES (1, 'заголовок', 'текст', 1); INSERT INTO public.post (id, header, text, author_id, blog_id) VALUES (1, 'заголовок', 'текст', 1, 2);
INSERT INTO public.post (id, header, text, author_id) VALUES (2, 'другой заголовок', 'другой текст', 2); INSERT INTO public.post (id, header, text, author_id, blog_id) VALUES (2, 'другой заголовок', 'другой текст', 2, 2);
-- --
@ -212,14 +195,6 @@ SELECT pg_catalog.setval('public.post_id_seq', 2, true);
SELECT pg_catalog.setval('public.user_id_seq', 2, true); SELECT pg_catalog.setval('public.user_id_seq', 2, true);
--
-- Name: alembic_version alembic_version_pkc; Type: CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.alembic_version
ADD CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num);
-- --
-- Name: blog blog_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres -- Name: blog blog_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
-- --
@ -260,6 +235,14 @@ ALTER TABLE ONLY public.post
ADD CONSTRAINT post_author_id_fkey FOREIGN KEY (author_id) REFERENCES public."user"(id); ADD CONSTRAINT post_author_id_fkey FOREIGN KEY (author_id) REFERENCES public."user"(id);
--
-- Name: post post_blog_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--
ALTER TABLE ONLY public.post
ADD CONSTRAINT post_blog_id_fkey FOREIGN KEY (blog_id) REFERENCES public.blog(id);
-- --
-- PostgreSQL database dump complete -- PostgreSQL database dump complete
-- --

View File

@ -3,6 +3,7 @@ from sqlalchemy.orm import Mapped, mapped_column
from .base import Base from .base import Base
from .user import User from .user import User
from .blog import Blog
class Post(Base): class Post(Base):
@ -12,3 +13,5 @@ class Post(Base):
text: Mapped[str] = mapped_column(default="") text: Mapped[str] = mapped_column(default="")
author_id: Mapped[int] = mapped_column(ForeignKey(User.id)) author_id: Mapped[int] = mapped_column(ForeignKey(User.id))
# author: Mapped[User] = relationship(lazy="selectin") # author: Mapped[User] = relationship(lazy="selectin")
blog_id: Mapped[int] = mapped_column(ForeignKey(Blog.id))
# blog: Mapped[Blog] = relationship(lazy="selectin")

View File

@ -1 +1,2 @@
from .healthcheck import healthcheck_router as healthcheck_router from .healthcheck import healthcheck_router as healthcheck_router
from .create_dataset import dataset_router as dataset_router

View File

@ -1,20 +1,50 @@
from typing import Annotated from fastapi import APIRouter
from fastapi import APIRouter, Depends from sqlalchemy import text, func, Date, case, select
from src.adapters.database.session import async_session_maker_db1, async_session_maker_db2
from src.adapters.database.models import User, Blog, Post, Log
from src.schemas.dataset_general import DatasetGeneralItem, DatasetGeneralOutput
dataset_router = APIRouter() dataset_router = APIRouter()
@dataset_router.get("/comments", response_model=None) @dataset_router.get("/comments", response_model=None)
async def get_database_comments(): async def get_database_comments():
pass async with async_session_maker_db1() as session:
# async with uow: pass
# return await FavouriteService(uow, jwt_token).get_favourites(
# page=page, limit=limit
# )
@dataset_router.get("/general", response_model=None)
"""
SELECT
CAST(log.datetime AS DATE) as date,
SUM(case when log.event_type = 'LOGIN' then 1 else 0 end) as login_count,
SUM(case when log.event_type = 'LOGOUT' then 1 else 0 end) as logout_count,
SUM(case when log.space_type = 'BLOG' then 1 else 0 end) as blog_operations
FROM log
GROUP BY CAST(log.datetime AS DATE);
"""
@dataset_router.get("/general", response_model=DatasetGeneralOutput)
async def get_database_general(): async def get_database_general():
pass async with async_session_maker_db2() as session:
stmt = (
select(
func.cast(Log.date_time, Date).label('date'),
func.sum(case((Log.event_type == 'LOGIN', 1), else_=0)).label('login_count'),
func.sum(case((Log.event_type == 'LOGOUT', 1), else_=0)).label('logout_count'),
func.sum(case((Log.space_type == 'BLOG', 1), else_=0)).label('blog_operations')
)
.group_by(func.cast(Log.date_time, Date))
)
orm_result = (await session.execute(stmt)).all()
items = []
for record in orm_result:
items.append(DatasetGeneralItem(
date=record[0],
login_count=record[1],
logout_count=record[2],
blog_operations=record[3]
))
return DatasetGeneralOutput(items=items)

View File

@ -1,7 +1,7 @@
from fastapi import APIRouter, FastAPI from fastapi import APIRouter, FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from src.api import healthcheck_router from src.api import healthcheck_router, dataset_router
app = FastAPI( app = FastAPI(
title="python_dev-backend", title="python_dev-backend",
@ -18,5 +18,6 @@ app.add_middleware(
app.include_router(healthcheck_router) app.include_router(healthcheck_router)
main_app_router = APIRouter(prefix="/api") main_app_router = APIRouter(prefix="/api")
main_app_router.include_router(dataset_router)
app.include_router(main_app_router) app.include_router(main_app_router)

View File

@ -0,0 +1,18 @@
from datetime import date
from pydantic import BaseModel, ConfigDict
class DatasetGeneralOutput(BaseModel):
model_config = ConfigDict(from_attributes=True)
items: list["DatasetGeneralItem"]
class DatasetGeneralItem(BaseModel):
model_config = ConfigDict(from_attributes=True)
date: date
login_count: int
logout_count: int
blog_operations: int