From 155cb136325e8bf6303cbea0b26684c8b6ef079a Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Thu, 30 Mar 2023 18:14:17 +0300 Subject: [PATCH 01/23] Initial commit --- .gitignore | 2 ++ CONTRIBUTING.md | 13 +++++++ README.md | 55 +++++++++++++++++++++++++---- services_backend/models/database.py | 2 +- services_backend/routes/button.py | 7 ++-- services_backend/routes/category.py | 30 ++++++++-------- 6 files changed, 84 insertions(+), 25 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/.gitignore b/.gitignore index b6e4761..ac27365 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,5 @@ dmypy.json # Pyre type checker .pyre/ +*.xml +*.iml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ae4a5fd --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# services-api + +Ссылки: + +1) Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка + + +Для запуска проекта нужно иметь доступ к БД профкома/иметь локальную БД. +Локальную БД можно поднять так: ссылка на вики которой нет + + +Переменные: +1) DB_DSN = 'postgres://логин:пароль/@адресс:порт/бд' diff --git a/README.md b/README.md index 4e7d1c2..44a2829 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,21 @@ # services-api -Бэкэдн сервисов приложения Твой ФФ для профкома ФФ МГУ +Бэкэдн сервисов приложения Твой ФФ для профкома ФФ МГУ. Описывает и реализует логику работы с кнопками и категориями в приложении. +Репозиторий был создан для упрощения работы фронтэнд-разработчиков с бэкэндом сервисов и для переноса данных кнопок и категорий из захардкодженного json файла в Postgresql базу данных (cringe). -## Запуск +## Функционал + +- Создание кнопок и категорий для отображения на фронте (в приложении) +- Управление доступами к категориями кнопок +- Редактирование любой информации о кнопке и категории + + +## Разработка +Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка + +CONTRIBUTING.md - нету + +## Quick Start 1) Перейдите в папку проекта @@ -10,18 +23,46 @@ ```console foo@bar:~$ python3 -m venv ./venv/ ``` - 3) Установите библиотеки ```console foo@bar:~$ pip install -m requirements.txt ``` -4) Запускайте приложение! +4) Установите все переменные окружения (см. CONTRIBUTING.MD) + +5) Запускайте приложение! ```console foo@bar:~$ python -m services-backend ``` -## ENV-file description -DB_DSN= +## Использование +1) Создание категории кнопок +*Необходимо иметь права services.category.create* + 1. Создать новую категорию по запросу `POST /category` с телом `{"name": "имя_категории", "type": "тип отображения категории в приложении"}` + + 2. *Необходимо иметь права services.button.create* Создать в категории новую кнопку по запросу `POST /category/id_категории/button` с телом `{"name": "имя кнопки", "icon": "ссылка на иконку", "link": "ссылка сервиса, на которую ведет кнопка", "type": "тип ссылки"}` + + 3. *Опционально* Навесить права запросом `POST /category/id_категории/scope` с телом `{"name": "название права доступа"}` + + +2) Получение категории кнопок +*Нет необходимых прав* + 1. Получить категории по запросу `GET /category` + 2. *Опционально* Выбрать отображение кнопок принадлежащих категории по запросу `GET /category?info=buttons` + + +3) Удаление категории кнопок. *Необходимо иметь права services.category.delete* + + ВАЖНОЕ УТОЧНЕНИЕ: При удалении категории все кнопки, принадлежащей ей также удаляются. + 1. Удалить категорию кнопок по запросу 'DELETE /category/id_категории + +## Параметризация и плагины: +Никаких настроек кроме стандартных нет + +## Ссылки: +Документация проекта - https://api.test.profcomff.com/?urls.primaryName=services# + +Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка + +CONTRIBUTING.md - нету ---- diff --git a/services_backend/models/database.py b/services_backend/models/database.py index c0b6cca..1d6c716 100644 --- a/services_backend/models/database.py +++ b/services_backend/models/database.py @@ -11,7 +11,7 @@ class Category(Base): order: Mapped[int] = mapped_column(Integer, default=1) name: Mapped[str] = mapped_column(String) type: Mapped[str] = mapped_column(String) - buttons: Mapped[list[Button]] = relationship("Button", back_populates="category", foreign_keys="Button.category_id") + buttons: Mapped[list[Button]] = relationship("Button", back_populates="category", foreign_keys="Button.category_id", order_by='Button.order') scopes: Mapped[list[Scope]] = relationship("Scope", back_populates="category") diff --git a/services_backend/routes/button.py b/services_backend/routes/button.py index f876826..4d83716 100644 --- a/services_backend/routes/button.py +++ b/services_backend/routes/button.py @@ -27,9 +27,12 @@ def create_button( category = db.session.query(Category).filter(Category.id == category_id).one_or_none() if not category: raise HTTPException(status_code=404, detail="Category does not exist") - last_button = db.session.query(Button).order_by(Button.order.desc()).first() + last_button = db.session.query(Button).filter(Button.category_id == category_id).order_by(Button.order.desc()).first() button = Button(**button_inp.dict(exclude_none=True)) button.category_id = category_id + for key in button_inp: + if not key[1]: + raise HTTPException(status_code=422, detail="Wrong schema") if last_button: button.order = last_button.order + 1 db.session.add(button) @@ -81,7 +84,7 @@ def get_button( def remove_button( button_id: int, category_id: int, - user=Depends(UnionAuth(['services.button.remove'])), + user=Depends(UnionAuth(['services.button.delete'])), ): """Удалить кнопку diff --git a/services_backend/routes/category.py b/services_backend/routes/category.py index 230c825..be1b9a6 100644 --- a/services_backend/routes/category.py +++ b/services_backend/routes/category.py @@ -5,19 +5,19 @@ from fastapi import APIRouter, Depends, HTTPException, Query from fastapi_sqlalchemy import db from sqlalchemy.orm import joinedload +from operator import itemgetter -from ..models.database import Button, Category, Scope +from ..models.database import Button, Category from .models.category import CategoryCreate, CategoryGet, CategoryUpdate - logger = logging.getLogger(__name__) category = APIRouter() @category.post("/", response_model=CategoryGet) def create_category( - category_inp: CategoryCreate, - user=Depends(UnionAuth(['services.category.create'])), + category_inp: CategoryCreate, + user=Depends(UnionAuth(['services.category.create'])), ): """Создает категорию @@ -35,8 +35,8 @@ def create_category( @category.get("/", response_model=list[CategoryGet], response_model_exclude_none=True) def get_categories( - info: list[Literal['buttons']] = Query([]), - user=Depends(UnionAuth(allow_none=True, auto_error=False)), + info: list[Literal['buttons']] = Query([]), + user=Depends(UnionAuth(allow_none=True, auto_error=False)), ): """Показывает список категорий @@ -63,8 +63,8 @@ def get_categories( @category.get("/{category_id}", response_model=CategoryGet, response_model_exclude_none=True) def get_category( - category_id: int, - user=Depends(UnionAuth(allow_none=True, auto_error=False)), + category_id: int, + user=Depends(UnionAuth(allow_none=True, auto_error=False)), ): """Показывает категорию @@ -79,7 +79,7 @@ def get_category( user_scopes = set([scope["name"] for scope in user["session_scopes"]] if user else []) category = db.session.query(Category).filter(Category.id == category_id).one_or_none() if not category or ( - category.scopes and not (user_scopes & set([scope.__dict__["name"] for scope in category.scopes])) + category.scopes and not (user_scopes & set([scope.__dict__["name"] for scope in category.scopes])) ): raise HTTPException(status_code=404, detail="Category does not exist") return { @@ -93,8 +93,8 @@ def get_category( @category.delete("/{category_id}", response_model=None) def remove_category( - category_id: int, - user=Depends(UnionAuth(['services.category.delete'])), + category_id: int, + user=Depends(UnionAuth(['services.category.delete'])), ): """Удаляет категорию и все кнопки в ней @@ -115,9 +115,9 @@ def remove_category( @category.patch("/{category_id}", response_model=CategoryUpdate) def update_category( - category_inp: CategoryUpdate, - category_id: int, - user=Depends(UnionAuth(['services.category.update'])), + category_inp: CategoryUpdate, + category_id: int, + user=Depends(UnionAuth(['services.category.update'])), ): """Обновляет категорию @@ -139,7 +139,7 @@ def update_category( raise HTTPException( status_code=400, detail=f"Can`t create category with order {category_inp.order}. " - f"Last category is {last_category.order}", + f"Last category is {last_category.order}", ) if category.order > category_inp.order: From ef3c496ccd1f4de25e379589e3a417fc7e7b439b Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Thu, 30 Mar 2023 18:16:27 +0300 Subject: [PATCH 02/23] Black doesn`t like me :( --- services_backend/models/database.py | 4 +++- services_backend/routes/button.py | 4 +++- services_backend/routes/category.py | 26 +++++++++++++------------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/services_backend/models/database.py b/services_backend/models/database.py index 1d6c716..5ba9397 100644 --- a/services_backend/models/database.py +++ b/services_backend/models/database.py @@ -11,7 +11,9 @@ class Category(Base): order: Mapped[int] = mapped_column(Integer, default=1) name: Mapped[str] = mapped_column(String) type: Mapped[str] = mapped_column(String) - buttons: Mapped[list[Button]] = relationship("Button", back_populates="category", foreign_keys="Button.category_id", order_by='Button.order') + buttons: Mapped[list[Button]] = relationship( + "Button", back_populates="category", foreign_keys="Button.category_id", order_by='Button.order' + ) scopes: Mapped[list[Scope]] = relationship("Scope", back_populates="category") diff --git a/services_backend/routes/button.py b/services_backend/routes/button.py index 4d83716..bc06705 100644 --- a/services_backend/routes/button.py +++ b/services_backend/routes/button.py @@ -27,7 +27,9 @@ def create_button( category = db.session.query(Category).filter(Category.id == category_id).one_or_none() if not category: raise HTTPException(status_code=404, detail="Category does not exist") - last_button = db.session.query(Button).filter(Button.category_id == category_id).order_by(Button.order.desc()).first() + last_button = ( + db.session.query(Button).filter(Button.category_id == category_id).order_by(Button.order.desc()).first() + ) button = Button(**button_inp.dict(exclude_none=True)) button.category_id = category_id for key in button_inp: diff --git a/services_backend/routes/category.py b/services_backend/routes/category.py index be1b9a6..6605d3f 100644 --- a/services_backend/routes/category.py +++ b/services_backend/routes/category.py @@ -16,8 +16,8 @@ @category.post("/", response_model=CategoryGet) def create_category( - category_inp: CategoryCreate, - user=Depends(UnionAuth(['services.category.create'])), + category_inp: CategoryCreate, + user=Depends(UnionAuth(['services.category.create'])), ): """Создает категорию @@ -35,8 +35,8 @@ def create_category( @category.get("/", response_model=list[CategoryGet], response_model_exclude_none=True) def get_categories( - info: list[Literal['buttons']] = Query([]), - user=Depends(UnionAuth(allow_none=True, auto_error=False)), + info: list[Literal['buttons']] = Query([]), + user=Depends(UnionAuth(allow_none=True, auto_error=False)), ): """Показывает список категорий @@ -63,8 +63,8 @@ def get_categories( @category.get("/{category_id}", response_model=CategoryGet, response_model_exclude_none=True) def get_category( - category_id: int, - user=Depends(UnionAuth(allow_none=True, auto_error=False)), + category_id: int, + user=Depends(UnionAuth(allow_none=True, auto_error=False)), ): """Показывает категорию @@ -79,7 +79,7 @@ def get_category( user_scopes = set([scope["name"] for scope in user["session_scopes"]] if user else []) category = db.session.query(Category).filter(Category.id == category_id).one_or_none() if not category or ( - category.scopes and not (user_scopes & set([scope.__dict__["name"] for scope in category.scopes])) + category.scopes and not (user_scopes & set([scope.__dict__["name"] for scope in category.scopes])) ): raise HTTPException(status_code=404, detail="Category does not exist") return { @@ -93,8 +93,8 @@ def get_category( @category.delete("/{category_id}", response_model=None) def remove_category( - category_id: int, - user=Depends(UnionAuth(['services.category.delete'])), + category_id: int, + user=Depends(UnionAuth(['services.category.delete'])), ): """Удаляет категорию и все кнопки в ней @@ -115,9 +115,9 @@ def remove_category( @category.patch("/{category_id}", response_model=CategoryUpdate) def update_category( - category_inp: CategoryUpdate, - category_id: int, - user=Depends(UnionAuth(['services.category.update'])), + category_inp: CategoryUpdate, + category_id: int, + user=Depends(UnionAuth(['services.category.update'])), ): """Обновляет категорию @@ -139,7 +139,7 @@ def update_category( raise HTTPException( status_code=400, detail=f"Can`t create category with order {category_inp.order}. " - f"Last category is {last_category.order}", + f"Last category is {last_category.order}", ) if category.order > category_inp.order: From 99458762536c1b44d803287f11340e63b4485677 Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Thu, 30 Mar 2023 18:17:22 +0300 Subject: [PATCH 03/23] ISort --- services_backend/routes/category.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services_backend/routes/category.py b/services_backend/routes/category.py index 6605d3f..81cd20f 100644 --- a/services_backend/routes/category.py +++ b/services_backend/routes/category.py @@ -1,15 +1,16 @@ import logging +from operator import itemgetter from typing import Literal from auth_lib.fastapi import UnionAuth from fastapi import APIRouter, Depends, HTTPException, Query from fastapi_sqlalchemy import db from sqlalchemy.orm import joinedload -from operator import itemgetter from ..models.database import Button, Category from .models.category import CategoryCreate, CategoryGet, CategoryUpdate + logger = logging.getLogger(__name__) category = APIRouter() From 6dfb524ac9b5538efff02badcacf7d225c71ed8b Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Fri, 31 Mar 2023 16:29:58 +0300 Subject: [PATCH 04/23] Update category.py --- services_backend/routes/category.py | 1 - 1 file changed, 1 deletion(-) diff --git a/services_backend/routes/category.py b/services_backend/routes/category.py index 81cd20f..8a0744d 100644 --- a/services_backend/routes/category.py +++ b/services_backend/routes/category.py @@ -1,5 +1,4 @@ import logging -from operator import itemgetter from typing import Literal from auth_lib.fastapi import UnionAuth From 16cabedaf3e989f413f0450f1b61f36add672469 Mon Sep 17 00:00:00 2001 From: Wudext Date: Wed, 5 Apr 2023 15:18:24 +0300 Subject: [PATCH 05/23] Fixing #22 --- services_backend/routes/models/button.py | 8 ++++---- services_backend/routes/models/category.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/services_backend/routes/models/button.py b/services_backend/routes/models/button.py index 938436a..e5b9a96 100644 --- a/services_backend/routes/models/button.py +++ b/services_backend/routes/models/button.py @@ -2,10 +2,10 @@ class ButtonCreate(Base): - icon: str | None - name: str | None - link: str | None - type: str | None + icon: str + name: str + link: str + type: str class ButtonUpdate(Base): diff --git a/services_backend/routes/models/category.py b/services_backend/routes/models/category.py index fffa8e3..7f3ee09 100644 --- a/services_backend/routes/models/category.py +++ b/services_backend/routes/models/category.py @@ -4,8 +4,8 @@ class CategoryCreate(Base): - type: str | None - name: str | None + type: str + name: str class CategoryUpdate(Base): From f22b360ba1ab5ab8e876c26a1cee563c32d36c6b Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Thu, 6 Apr 2023 10:25:14 +0300 Subject: [PATCH 06/23] Update .gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index ac27365..b6e4761 100644 --- a/.gitignore +++ b/.gitignore @@ -127,5 +127,3 @@ dmypy.json # Pyre type checker .pyre/ -*.xml -*.iml From e44e6f21b0e4b57c8320d6139cc5e86902933bfb Mon Sep 17 00:00:00 2001 From: Wudext Date: Thu, 6 Apr 2023 10:36:17 +0300 Subject: [PATCH 07/23] CONTRIBUTING.md and README.md --- CONTRIBUTING.md | 2 +- README.md | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ae4a5fd..ffe9966 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,4 +10,4 @@ Переменные: -1) DB_DSN = 'postgres://логин:пароль/@адресс:порт/бд' +1) DB_DSN = 'postgres://логин:пароль@адрес:порт/бд' diff --git a/README.md b/README.md index 44a2829..9bc8393 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # services-api -Бэкэдн сервисов приложения Твой ФФ для профкома ФФ МГУ. Описывает и реализует логику работы с кнопками и категориями в приложении. -Репозиторий был создан для упрощения работы фронтэнд-разработчиков с бэкэндом сервисов и для переноса данных кнопок и категорий из захардкодженного json файла в Postgresql базу данных (cringe). +Бэкэдн сервисов приложения Твой ФФ для профкома ФФ МГУ. Реализует логику работы с кнопками и категориями в приложении. +Репозиторий был создан для упрощения работы фронтэнд-разработчиков с бэкэндом сервисов, для переноса данных кнопок и категорий из захардкодженного json файла в Postgresql базу данных (cringe) и для разграничения доступа. ## Функционал - Создание кнопок и категорий для отображения на фронте (в приложении) -- Управление доступами к категориями кнопок -- Редактирование любой информации о кнопке и категории +- Управление доступами к категориям кнопок +- Редактирование любых атрибутов/полей кнопое и категорий ## Разработка @@ -27,7 +27,7 @@ foo@bar:~$ python3 -m venv ./venv/ ```console foo@bar:~$ pip install -m requirements.txt ``` -4) Установите все переменные окружения (см. CONTRIBUTING.MD) +4) Установите все переменные окружения (см. CONTRIBUTING.md) 5) Запускайте приложение! ```console @@ -42,10 +42,10 @@ foo@bar:~$ python -m services-backend 2. *Необходимо иметь права services.button.create* Создать в категории новую кнопку по запросу `POST /category/id_категории/button` с телом `{"name": "имя кнопки", "icon": "ссылка на иконку", "link": "ссылка сервиса, на которую ведет кнопка", "type": "тип ссылки"}` - 3. *Опционально* Навесить права запросом `POST /category/id_категории/scope` с телом `{"name": "название права доступа"}` + 3. *Опционально* Навесить права запросом `POST /category/{category_id}/scope` с телом `{"name": "название права доступа"}` -2) Получение категории кнопок +2) Получение категорий кнопок *Нет необходимых прав* 1. Получить категории по запросу `GET /category` 2. *Опционально* Выбрать отображение кнопок принадлежащих категории по запросу `GET /category?info=buttons` @@ -64,5 +64,5 @@ foo@bar:~$ python -m services-backend Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка -CONTRIBUTING.md - нету +CONTRIBUTING.md - https://github.com/profcomff/services-api/blob/f22b360ba1ab5ab8e876c26a1cee563c32d36c6b/CONTRIBUTING.md (потом поменяю) From 4cb350a57adcca5ef01808cce5a1bc67b8ef4ac3 Mon Sep 17 00:00:00 2001 From: Wudext Date: Thu, 6 Apr 2023 10:41:06 +0300 Subject: [PATCH 08/23] Descriptions --- services_backend/routes/models/button.py | 9 +++++---- services_backend/routes/models/category.py | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/services_backend/routes/models/button.py b/services_backend/routes/models/button.py index e5b9a96..52ba64d 100644 --- a/services_backend/routes/models/button.py +++ b/services_backend/routes/models/button.py @@ -1,11 +1,12 @@ from .base import Base +from pydantic import Field class ButtonCreate(Base): - icon: str - name: str - link: str - type: str + icon: str = Field(description='Иконка кнопки') + name: str = Field(description='Название кнопки') + link: str = Field(description='Ссылка, на которую перенаправляет кнопка') + type: str = Field(description='Тип открываемой ссылки') class ButtonUpdate(Base): diff --git a/services_backend/routes/models/category.py b/services_backend/routes/models/category.py index 7f3ee09..c097e5d 100644 --- a/services_backend/routes/models/category.py +++ b/services_backend/routes/models/category.py @@ -1,11 +1,12 @@ from .base import Base from .button import ButtonGet from .scope import ScopeGet +from pydantic import Field class CategoryCreate(Base): - type: str - name: str + type: str = Field(description='Тип отображения категории') + name: str = Field(description='Имя категории') class CategoryUpdate(Base): From 3baf8cf40cb3d44fb1becda4b39606000dda51b9 Mon Sep 17 00:00:00 2001 From: Wudext Date: Thu, 6 Apr 2023 10:43:35 +0300 Subject: [PATCH 09/23] Black and Isort (again) --- services_backend/routes/models/button.py | 3 ++- services_backend/routes/models/category.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/services_backend/routes/models/button.py b/services_backend/routes/models/button.py index 52ba64d..d317bbc 100644 --- a/services_backend/routes/models/button.py +++ b/services_backend/routes/models/button.py @@ -1,6 +1,7 @@ -from .base import Base from pydantic import Field +from .base import Base + class ButtonCreate(Base): icon: str = Field(description='Иконка кнопки') diff --git a/services_backend/routes/models/category.py b/services_backend/routes/models/category.py index c097e5d..6c8774f 100644 --- a/services_backend/routes/models/category.py +++ b/services_backend/routes/models/category.py @@ -1,7 +1,8 @@ +from pydantic import Field + from .base import Base from .button import ButtonGet from .scope import ScopeGet -from pydantic import Field class CategoryCreate(Base): From 7c43f85321d04c5b028761c0889d08d7d076bde2 Mon Sep 17 00:00:00 2001 From: Wudext Date: Thu, 6 Apr 2023 14:00:51 +0300 Subject: [PATCH 10/23] Final commit (i hope) --- CONTRIBUTING.md | 5 ++++- README.md | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ffe9966..1e8916e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,10 @@ Для запуска проекта нужно иметь доступ к БД профкома/иметь локальную БД. -Локальную БД можно поднять так: ссылка на вики которой нет + +Локальную БД можно поднять так: +- Установить Docker +- В терминале запустить: ```docker run -d -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust --name db-services-backend postgres:15``` Переменные: diff --git a/README.md b/README.md index 9bc8393..22df9e3 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ## Разработка Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка -CONTRIBUTING.md - нету +CONTRIBUTING.md - https://github.com/profcomff/services-api/blob/f22b360ba1ab5ab8e876c26a1cee563c32d36c6b/CONTRIBUTING.md (потом поменяю) ## Quick Start From 1dd9056cc72734191151acdd11ea963369ccb553 Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Thu, 6 Apr 2023 15:10:47 +0300 Subject: [PATCH 11/23] Update button.py --- services_backend/routes/button.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/services_backend/routes/button.py b/services_backend/routes/button.py index bc06705..f7eb7e1 100644 --- a/services_backend/routes/button.py +++ b/services_backend/routes/button.py @@ -32,9 +32,6 @@ def create_button( ) button = Button(**button_inp.dict(exclude_none=True)) button.category_id = category_id - for key in button_inp: - if not key[1]: - raise HTTPException(status_code=422, detail="Wrong schema") if last_button: button.order = last_button.order + 1 db.session.add(button) From 90b8f908d70afc7b851bc4671240a74cc96cae05 Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Fri, 7 Apr 2023 21:30:24 +0300 Subject: [PATCH 12/23] Enum + README + migrations --- README.md | 4 ++-- migrations/versions/6a486347af93_order.py | 7 ++++--- services_backend/models/database.py | 10 +++++++++- services_backend/routes/models/button.py | 3 ++- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 22df9e3..1711d8b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ## Разработка Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка -CONTRIBUTING.md - https://github.com/profcomff/services-api/blob/f22b360ba1ab5ab8e876c26a1cee563c32d36c6b/CONTRIBUTING.md (потом поменяю) +CONTRIBUTING.md - [CONTRIBUTING.md](services-api/CONTRIBUTING.md) ## Quick Start @@ -64,5 +64,5 @@ foo@bar:~$ python -m services-backend Backend разработка – https://github.com/profcomff/.github/wiki/%5Bdev%5D-Backend-разработка -CONTRIBUTING.md - https://github.com/profcomff/services-api/blob/f22b360ba1ab5ab8e876c26a1cee563c32d36c6b/CONTRIBUTING.md (потом поменяю) +CONTRIBUTING.md - [CONTRIBUTING.md](services-api/CONTRIBUTING.md) diff --git a/migrations/versions/6a486347af93_order.py b/migrations/versions/6a486347af93_order.py index 02b12cf..9131633 100644 --- a/migrations/versions/6a486347af93_order.py +++ b/migrations/versions/6a486347af93_order.py @@ -26,10 +26,13 @@ def upgrade(): conn.execute( sa.text( f"""UPDATE "button" + SELECT * FROM categories + SET "order"={i + 1}, "link"='#', "type"='external' - WHERE id={res[i][0]}""" + WHERE id={res[i][0]} + WHERE category_id = category.id""" ) ) op.alter_column('button', 'order', nullable=False) @@ -55,7 +58,6 @@ def upgrade(): def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### op.alter_column('category', 'type', existing_type=sa.VARCHAR(), nullable=True) op.alter_column('category', 'name', existing_type=sa.VARCHAR(), nullable=True) op.drop_column('category', 'order') @@ -65,4 +67,3 @@ def downgrade(): op.drop_column('button', 'type') op.drop_column('button', 'link') op.drop_column('button', 'order') - # ### end Alembic commands ### diff --git a/services_backend/models/database.py b/services_backend/models/database.py index 5ba9397..e810453 100644 --- a/services_backend/models/database.py +++ b/services_backend/models/database.py @@ -1,5 +1,7 @@ from __future__ import annotations +from enum import Enum +from sqlalchemy import Enum as DbEnum from sqlalchemy import ForeignKey, Integer, String from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -17,6 +19,12 @@ class Category(Base): scopes: Mapped[list[Scope]] = relationship("Scope", back_populates="category") +class Type(str, Enum): + INAPP: str = "inapp" + INTERNAL: str = "internal" + EXTERNAL: str = "external" + + class Button(Base): id: Mapped[int] = mapped_column(Integer, primary_key=True) name: Mapped[str] = mapped_column(String) @@ -25,7 +33,7 @@ class Button(Base): category: Mapped[Category] = relationship("Category", back_populates="buttons", foreign_keys=[category_id]) icon: Mapped[str] = mapped_column(String) link: Mapped[str] = mapped_column(String) - type: Mapped[str] = mapped_column(String) + type: Mapped[Type] = mapped_column(DbEnum(Type, native_enum=False), nullable=False) class Scope(Base): diff --git a/services_backend/routes/models/button.py b/services_backend/routes/models/button.py index d317bbc..93a2ae6 100644 --- a/services_backend/routes/models/button.py +++ b/services_backend/routes/models/button.py @@ -1,13 +1,14 @@ from pydantic import Field from .base import Base +from ...models.database import Type class ButtonCreate(Base): icon: str = Field(description='Иконка кнопки') name: str = Field(description='Название кнопки') link: str = Field(description='Ссылка, на которую перенаправляет кнопка') - type: str = Field(description='Тип открываемой ссылки') + type: Type = Field(description='Тип открываемой ссылки') class ButtonUpdate(Base): From 73518e7ed5be9a97e0b4aeb56d0afda4c9ac8d5c Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Fri, 7 Apr 2023 22:34:03 +0300 Subject: [PATCH 13/23] Update conftest.py --- tests/api/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api/conftest.py b/tests/api/conftest.py index a43f479..c32b8fb 100644 --- a/tests/api/conftest.py +++ b/tests/api/conftest.py @@ -19,7 +19,7 @@ def db_category(dbsession): @pytest.fixture def db_button(dbsession, db_category): - _button = Button(name='button', category_id=db_category.id, icon='test', link='g', type='d') + _button = Button(name='button', category_id=db_category.id, icon='test', link='g', type='inapp') dbsession.add(_button) dbsession.commit() _button = dbsession.query(Button).filter(Button.id == _button.id).one_or_none() From 7f3718cf8fa0c4805484df7061f42d325e8a2227 Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Fri, 7 Apr 2023 22:35:43 +0300 Subject: [PATCH 14/23] Update button.py --- tests/api/button.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/api/button.py b/tests/api/button.py index f0cbffd..b841b23 100644 --- a/tests/api/button.py +++ b/tests/api/button.py @@ -19,7 +19,7 @@ def test_post_success(self, client, db_category, dbsession): "icon": "https://lh3.googleusercontent.com/yURn6ISxDySTdXZAW2PUcADMnU3y9YX0M1RyXOH8a3sa1Tr0pHhPLGw5BKuiLiXa3Eh0fyHm7Dfsd9FodK3fxJge6g=w640-h400-e365-rj-sc0x00ffffff", "name": "string", "link": "google.com", - "type": "test", + "type": "inapp", } res = client.post(f"/category/{db_category.id}/button/", data=json.dumps(body)) assert res.status_code == status.HTTP_200_OK @@ -57,7 +57,7 @@ def test_delete_by_id_success(self, client, dbsession, db_button, db_category): assert get_res.status_code == status.HTTP_404_NOT_FOUND def test_patch_by_id_success(self, db_button, client, db_category): - body = {"icon": "cool icon", "name": "nice name", "order": 2, "link": "ya.ru", "type": "nice type"} + body = {"icon": "cool icon", "name": "nice name", "order": 2, "link": "ya.ru", "type": "inapp"} res = client.patch(f"/category/{db_category.id}/button/{db_button.id}", data=json.dumps(body)) assert res.status_code == status.HTTP_200_OK res_body = res.json() @@ -99,7 +99,7 @@ def test_create_first(self, client, db_button, db_category): "icon": "test", "name": "test", "link": "test", - "type": "test", + "type": "inapp", } res = client.post(f"/category/{db_category.id}/button/", data=json.dumps(body)) @@ -115,7 +115,7 @@ def test_patch_order_fail(self, client, db_button, db_category): "icon": "test", "name": "new", "link": "test", - "type": "test", + "type": "inapp", } res1 = client.post(f"/category/{db_category.id}/button/", data=json.dumps(body)) assert res1.status_code == status.HTTP_200_OK @@ -132,7 +132,7 @@ def test_patch_negative_order_fail(self, db_button, client, db_category): "icon": "test", "name": "new", "link": "test", - "type": "test", + "type": "inapp", } res = client.post(f"/category/{db_category.id}/button/", data=json.dumps(body)) res1 = client.patch(f"/category/{db_category.id}/button/{res.json()['id']}", data=json.dumps({"order": -10})) @@ -143,7 +143,7 @@ def test_delete_order(self, db_button, client, db_category): "icon": "test", "name": "new", "link": "test", - "type": "test", + "type": "inapp", } res1 = client.post(f"/category/{db_category.id}/button/", data=json.dumps(body)) assert res1.status_code == status.HTTP_200_OK From ec098ecf19589ab78a54beb5fa1997e94be7b3e8 Mon Sep 17 00:00:00 2001 From: Wudext Date: Sat, 8 Apr 2023 08:51:16 +0300 Subject: [PATCH 15/23] Fixing migrations --- migrations/versions/6a486347af93_order.py | 31 +++++++++++------------ services_backend/models/database.py | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/migrations/versions/6a486347af93_order.py b/migrations/versions/6a486347af93_order.py index 9131633..6760cc0 100644 --- a/migrations/versions/6a486347af93_order.py +++ b/migrations/versions/6a486347af93_order.py @@ -21,20 +21,19 @@ def upgrade(): op.add_column('button', sa.Column('link', sa.String(), nullable=True)) op.add_column('button', sa.Column('type', sa.String(), nullable=True)) conn = op.get_bind() - res = conn.execute(sa.text("select id from button")).fetchall() - for i in range(0, len(res)): - conn.execute( - sa.text( - f"""UPDATE "button" - SELECT * FROM categories - - SET "order"={i + 1}, - "link"='#', - "type"='external' - WHERE id={res[i][0]} - WHERE category_id = category.id""" + res_c = conn.execute(sa.text("select * from category")).fetchall() + for category in res_c: + res_b = conn.execute(sa.text(f"select id from button where button.id = {category[0]}")).fetchall() + for i in range(0, len(res_b)): + conn.execute( + sa.text( + f"""UPDATE "button" + SET "order"={i + 1}, + "link"='#', + "type"='external' + WHERE id={res_b[i][0]}""" + ) ) - ) op.alter_column('button', 'order', nullable=False) op.alter_column('button', 'link', nullable=False) op.alter_column('button', 'type', nullable=False) @@ -42,13 +41,13 @@ def upgrade(): op.alter_column('button', 'category_id', existing_type=sa.INTEGER(), nullable=False) op.alter_column('button', 'icon', existing_type=sa.VARCHAR(), nullable=False) op.add_column('category', sa.Column('order', sa.Integer(), nullable=True)) - res = conn.execute(sa.text("select id from category")).fetchall() - for i in range(0, len(res)): + res_c = conn.execute(sa.text("select id from category")).fetchall() + for i in range(0, len(res_c)): conn.execute( sa.text( f"""UPDATE "category" SET "order"={i + 1} - WHERE id={res[i][0]}""" + WHERE id={res_c[i][0]}""" ) ) op.alter_column('category', 'order', nullable=False) diff --git a/services_backend/models/database.py b/services_backend/models/database.py index e810453..ea5d5dd 100644 --- a/services_backend/models/database.py +++ b/services_backend/models/database.py @@ -3,7 +3,7 @@ from enum import Enum from sqlalchemy import Enum as DbEnum from sqlalchemy import ForeignKey, Integer, String -from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm import Mapped, relationship, mapped_column from .base import Base From 767b2d32ace68e77c41f86b6d3c5fb33678a955c Mon Sep 17 00:00:00 2001 From: Wudext Date: Sat, 8 Apr 2023 08:54:12 +0300 Subject: [PATCH 16/23] =?UTF-8?q?Black=20and=20Isort=20(=D0=BD=D0=B0=D0=B4?= =?UTF-8?q?=D0=BE=D0=B5=D0=BB=D0=B8=20=D1=83=D0=B6=D0=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services_backend/models/database.py | 3 ++- services_backend/routes/models/button.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/services_backend/models/database.py b/services_backend/models/database.py index ea5d5dd..6568f41 100644 --- a/services_backend/models/database.py +++ b/services_backend/models/database.py @@ -1,9 +1,10 @@ from __future__ import annotations from enum import Enum + from sqlalchemy import Enum as DbEnum from sqlalchemy import ForeignKey, Integer, String -from sqlalchemy.orm import Mapped, relationship, mapped_column +from sqlalchemy.orm import Mapped, mapped_column, relationship from .base import Base diff --git a/services_backend/routes/models/button.py b/services_backend/routes/models/button.py index 93a2ae6..cb48544 100644 --- a/services_backend/routes/models/button.py +++ b/services_backend/routes/models/button.py @@ -1,7 +1,7 @@ from pydantic import Field -from .base import Base from ...models.database import Type +from .base import Base class ButtonCreate(Base): From 27361ad5c706f65c5f3fbec7a7c68ae24b8121cd Mon Sep 17 00:00:00 2001 From: Stanislav Roslavtsev Date: Sun, 9 Apr 2023 13:59:43 +0300 Subject: [PATCH 17/23] Fixing --- README.md | 2 +- migrations/versions/6a486347af93_order.py | 22 ++++++------- migrations/versions/d35e88f39f85_fixing.py | 37 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 migrations/versions/d35e88f39f85_fixing.py diff --git a/README.md b/README.md index 1711d8b..2eaf00f 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ foo@bar:~$ python -m services-backend 3) Удаление категории кнопок. *Необходимо иметь права services.category.delete* ВАЖНОЕ УТОЧНЕНИЕ: При удалении категории все кнопки, принадлежащей ей также удаляются. - 1. Удалить категорию кнопок по запросу 'DELETE /category/id_категории + 1. Удалить категорию кнопок по запросу 'DELETE /category/{category_id} ## Параметризация и плагины: Никаких настроек кроме стандартных нет diff --git a/migrations/versions/6a486347af93_order.py b/migrations/versions/6a486347af93_order.py index 6760cc0..b3e6e02 100644 --- a/migrations/versions/6a486347af93_order.py +++ b/migrations/versions/6a486347af93_order.py @@ -21,19 +21,17 @@ def upgrade(): op.add_column('button', sa.Column('link', sa.String(), nullable=True)) op.add_column('button', sa.Column('type', sa.String(), nullable=True)) conn = op.get_bind() - res_c = conn.execute(sa.text("select * from category")).fetchall() - for category in res_c: - res_b = conn.execute(sa.text(f"select id from button where button.id = {category[0]}")).fetchall() - for i in range(0, len(res_b)): - conn.execute( - sa.text( - f"""UPDATE "button" - SET "order"={i + 1}, - "link"='#', - "type"='external' - WHERE id={res_b[i][0]}""" - ) + res = conn.execute(sa.text("select * from button")).fetchall() + for i in range(0, len(res)): + conn.execute( + sa.text( + f"""UPDATE "button" + SET "order"={i + 1}, + "link"=f'{res[i][5]}', + "type"='inapp' + WHERE id={res[i][0]}""" ) + ) op.alter_column('button', 'order', nullable=False) op.alter_column('button', 'link', nullable=False) op.alter_column('button', 'type', nullable=False) diff --git a/migrations/versions/d35e88f39f85_fixing.py b/migrations/versions/d35e88f39f85_fixing.py new file mode 100644 index 0000000..b0d52d0 --- /dev/null +++ b/migrations/versions/d35e88f39f85_fixing.py @@ -0,0 +1,37 @@ +"""Fixing + +Revision ID: d35e88f39f85 +Revises: 660bb7891726 +Create Date: 2023-04-09 11:28:59.326067 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'd35e88f39f85' +down_revision = '660bb7891726' +branch_labels = None +depends_on = None + + +def upgrade(): + conn = op.get_bind() + res_c = conn.execute(sa.text("select * from category")).fetchall() + for category in res_c: + res_b = conn.execute(sa.text(f"select * from button WHERE category_id={category[0]}")).fetchall() + for i in range(0, len(res_b)): + conn.execute( + sa.text( + f"""UPDATE "button" + SET "order"={i + 1}, + "link"='{res_b[i][5]}', + "type"='{res_b[i][6]}' + WHERE id={res_b[i][0]}""" + ) + ) + + +def downgrade(): + pass From 11459c1f849ba88dc6de60955d308887d2aefd07 Mon Sep 17 00:00:00 2001 From: Wudext Date: Mon, 10 Apr 2023 08:49:20 +0300 Subject: [PATCH 18/23] Last commint (again) --- migrations/versions/6a486347af93_order.py | 2 +- migrations/versions/d35e88f39f85_fixing.py | 29 +++++++++++++++++++--- services_backend/routes/models/button.py | 26 +++++++++---------- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/migrations/versions/6a486347af93_order.py b/migrations/versions/6a486347af93_order.py index b3e6e02..d2dce48 100644 --- a/migrations/versions/6a486347af93_order.py +++ b/migrations/versions/6a486347af93_order.py @@ -27,7 +27,7 @@ def upgrade(): sa.text( f"""UPDATE "button" SET "order"={i + 1}, - "link"=f'{res[i][5]}', + "link"=#', "type"='inapp' WHERE id={res[i][0]}""" ) diff --git a/migrations/versions/d35e88f39f85_fixing.py b/migrations/versions/d35e88f39f85_fixing.py index b0d52d0..f43d42b 100644 --- a/migrations/versions/d35e88f39f85_fixing.py +++ b/migrations/versions/d35e88f39f85_fixing.py @@ -5,8 +5,10 @@ Create Date: 2023-04-09 11:28:59.326067 """ -from alembic import op +import operator + import sqlalchemy as sa +from alembic import op # revision identifiers, used by Alembic. @@ -20,7 +22,10 @@ def upgrade(): conn = op.get_bind() res_c = conn.execute(sa.text("select * from category")).fetchall() for category in res_c: - res_b = conn.execute(sa.text(f"select * from button WHERE category_id={category[0]}")).fetchall() + res_b = sorted( + conn.execute(sa.text(f"select * from button WHERE category_id={category[0]}")).fetchall(), + key=operator.itemgetter(2), + ) for i in range(0, len(res_b)): conn.execute( sa.text( @@ -34,4 +39,22 @@ def upgrade(): def downgrade(): - pass + k = 0 + conn = op.get_bind() + res_c = conn.execute(sa.text("select * from category")).fetchall() + for category in res_c: + res_b = sorted( + conn.execute(sa.text(f"select * from button WHERE category_id={category[0]}")).fetchall(), + key=operator.itemgetter(2), + ) + for i in range(0, len(res_b)): + conn.execute( + sa.text( + f"""UPDATE "button" + SET "order"={k + 1}, + "link"='{res_b[i][5]}', + "type"='{res_b[i][6]}' + WHERE id={res_b[i][0]}""" + ) + ) + k += 1 diff --git a/services_backend/routes/models/button.py b/services_backend/routes/models/button.py index cb48544..59cca46 100644 --- a/services_backend/routes/models/button.py +++ b/services_backend/routes/models/button.py @@ -8,22 +8,22 @@ class ButtonCreate(Base): icon: str = Field(description='Иконка кнопки') name: str = Field(description='Название кнопки') link: str = Field(description='Ссылка, на которую перенаправляет кнопка') - type: Type = Field(description='Тип открываемой ссылки') + type: Type = Field(description='Тип открываемой ссылки (Ссылка приложения/Браузер в приложении/Браузер') class ButtonUpdate(Base): - category_id: int | None - icon: str | None - name: str | None - order: int | None - link: str | None - type: str | None + category_id: int | None = Field(description='Айди категории') + icon: str | None = Field(description='Иконка кнопки') + name: str | None = Field(description='Название кнопки') + order: int | None = Field(description='Порядок, в котором отображаются кнопки') + link: str | None = Field(description='Ссылка, на которую перенаправляет кнопка') + type: str | None = Field(description='Тип открываемой ссылки (Ссылка приложения/Браузер в приложении/Браузер') class ButtonGet(Base): - id: int - order: int - icon: str | None - name: str | None - link: str | None - type: str | None + id: int = Field(description='Айди кнопки') + order: int = Field(description='Порядок, в котором отображаются кнопки') + icon: str | None = Field(description='Иконка кнопки') + name: str | None = Field(description='Название кнопки') + link: str | None = Field(description='Ссылка, на которую перенаправляет кнопка') + type: str | None = Field(description='Тип открываемой ссылки (Ссылка приложения/Браузер в приложении/Браузер') From 56e9d52e109241527570533a8bf49945386b999f Mon Sep 17 00:00:00 2001 From: Wudext Date: Mon, 10 Apr 2023 13:54:15 +0300 Subject: [PATCH 19/23] Please let it end --- migrations/versions/d35e88f39f85_fixing.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/migrations/versions/d35e88f39f85_fixing.py b/migrations/versions/d35e88f39f85_fixing.py index f43d42b..6dedfa5 100644 --- a/migrations/versions/d35e88f39f85_fixing.py +++ b/migrations/versions/d35e88f39f85_fixing.py @@ -20,12 +20,10 @@ def upgrade(): conn = op.get_bind() - res_c = conn.execute(sa.text("select * from category")).fetchall() + res_c = conn.execute(sa.text("select * from category ORDER BY category.order")).fetchall() for category in res_c: res_b = sorted( - conn.execute(sa.text(f"select * from button WHERE category_id={category[0]}")).fetchall(), - key=operator.itemgetter(2), - ) + conn.execute(sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order")).fetchall()) for i in range(0, len(res_b)): conn.execute( sa.text( @@ -41,12 +39,10 @@ def upgrade(): def downgrade(): k = 0 conn = op.get_bind() - res_c = conn.execute(sa.text("select * from category")).fetchall() + res_c = conn.execute(sa.text("select * from category ORDER BY category.order")).fetchall() for category in res_c: res_b = sorted( - conn.execute(sa.text(f"select * from button WHERE category_id={category[0]}")).fetchall(), - key=operator.itemgetter(2), - ) + conn.execute(sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order")).fetchall()) for i in range(0, len(res_b)): conn.execute( sa.text( From fbc2b4b3e896b562e50522fb5c338e0c293b94a8 Mon Sep 17 00:00:00 2001 From: Wudext Date: Mon, 10 Apr 2023 14:19:02 +0300 Subject: [PATCH 20/23] Update 6a486347af93_order.py --- migrations/versions/6a486347af93_order.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/versions/6a486347af93_order.py b/migrations/versions/6a486347af93_order.py index d2dce48..bd87bed 100644 --- a/migrations/versions/6a486347af93_order.py +++ b/migrations/versions/6a486347af93_order.py @@ -27,8 +27,8 @@ def upgrade(): sa.text( f"""UPDATE "button" SET "order"={i + 1}, - "link"=#', - "type"='inapp' + "link"='#', + "type"='external' WHERE id={res[i][0]}""" ) ) From ecc1a90013d849baaea8e83b14fb3a4e1653bee9 Mon Sep 17 00:00:00 2001 From: Wudext Date: Mon, 10 Apr 2023 14:19:31 +0300 Subject: [PATCH 21/23] Black (3d time) --- migrations/versions/d35e88f39f85_fixing.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/migrations/versions/d35e88f39f85_fixing.py b/migrations/versions/d35e88f39f85_fixing.py index 6dedfa5..d7096ab 100644 --- a/migrations/versions/d35e88f39f85_fixing.py +++ b/migrations/versions/d35e88f39f85_fixing.py @@ -23,7 +23,10 @@ def upgrade(): res_c = conn.execute(sa.text("select * from category ORDER BY category.order")).fetchall() for category in res_c: res_b = sorted( - conn.execute(sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order")).fetchall()) + conn.execute( + sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order") + ).fetchall() + ) for i in range(0, len(res_b)): conn.execute( sa.text( @@ -42,7 +45,10 @@ def downgrade(): res_c = conn.execute(sa.text("select * from category ORDER BY category.order")).fetchall() for category in res_c: res_b = sorted( - conn.execute(sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order")).fetchall()) + conn.execute( + sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order") + ).fetchall() + ) for i in range(0, len(res_b)): conn.execute( sa.text( From c7e0c6bc69562d434cc365f9bba49731254d0260 Mon Sep 17 00:00:00 2001 From: Wudext Date: Mon, 10 Apr 2023 14:24:49 +0300 Subject: [PATCH 22/23] aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --- migrations/versions/d35e88f39f85_fixing.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/migrations/versions/d35e88f39f85_fixing.py b/migrations/versions/d35e88f39f85_fixing.py index d7096ab..92c5493 100644 --- a/migrations/versions/d35e88f39f85_fixing.py +++ b/migrations/versions/d35e88f39f85_fixing.py @@ -22,11 +22,9 @@ def upgrade(): conn = op.get_bind() res_c = conn.execute(sa.text("select * from category ORDER BY category.order")).fetchall() for category in res_c: - res_b = sorted( - conn.execute( + res_b = conn.execute( sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order") ).fetchall() - ) for i in range(0, len(res_b)): conn.execute( sa.text( @@ -44,11 +42,9 @@ def downgrade(): conn = op.get_bind() res_c = conn.execute(sa.text("select * from category ORDER BY category.order")).fetchall() for category in res_c: - res_b = sorted( - conn.execute( + res_b = conn.execute( sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order") ).fetchall() - ) for i in range(0, len(res_b)): conn.execute( sa.text( From f8ebef943bfdc026fb6f41389b040da840b6d1e1 Mon Sep 17 00:00:00 2001 From: Wudext Date: Mon, 10 Apr 2023 14:25:05 +0300 Subject: [PATCH 23/23] Update d35e88f39f85_fixing.py --- migrations/versions/d35e88f39f85_fixing.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/migrations/versions/d35e88f39f85_fixing.py b/migrations/versions/d35e88f39f85_fixing.py index 92c5493..f755c78 100644 --- a/migrations/versions/d35e88f39f85_fixing.py +++ b/migrations/versions/d35e88f39f85_fixing.py @@ -23,8 +23,8 @@ def upgrade(): res_c = conn.execute(sa.text("select * from category ORDER BY category.order")).fetchall() for category in res_c: res_b = conn.execute( - sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order") - ).fetchall() + sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order") + ).fetchall() for i in range(0, len(res_b)): conn.execute( sa.text( @@ -43,8 +43,8 @@ def downgrade(): res_c = conn.execute(sa.text("select * from category ORDER BY category.order")).fetchall() for category in res_c: res_b = conn.execute( - sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order") - ).fetchall() + sa.text(f"select * from button WHERE category_id={category[0]} ORDER BY button.order") + ).fetchall() for i in range(0, len(res_b)): conn.execute( sa.text(