Временные базы данных в приложении не идеальны для веб-приложений. Любое неудачное событие, такое как резкое отключение или перезапуск приложения, приведет к общей потере сохраненных данных.
Это третий пост в нашей серии о том, как разработать приложение Fastapi с Okteto. В предыдущих постах вы узнали, как развертывать приложения непосредственно из вашей консоли, используя стеки Okteto и как развернуть их непосредственно из пользовательского интерфейса Okteto.
В этом уроке вы будете добавлять базу данных для лучшего хранения данных о вашем приложении, а затем вы развернете обновленную версию в свое пространство имен Okteto непосредственно из вашей командной строки.
Начальная настройка
Начните с создания Вилка приложения от GitHub а затем клонировать его на местном уровне.
git clone https://github.com/okteto/fastapi-crud
В вашем локальном клоне установите его, используя следующие команды:
$ cd fastapi-crud $ python3 -m venv venv && source venv/bin/activate (venv)$ pip install -r requirements.txt
Убедитесь, что настройка завершена путем запуска:
python3 main.py
После проверки установки обновите Dockerhubusername
переменная в вашем файле стека в okteto.dev
Анкет Развернуть приложение с помощью команды:
(venv)$ okteto stack deploy --build
Создание нового филиала
Для этой статьи мы создадим новую филиал. Это позволяет вам дифференцировать первый пост в серии от этого.
Из вашей консоли запустите команду:
git checkout -b mongo-crud
Команда выше создает новую филиал Монго-крик
С происхождением, указывающим на Главный
Анкет
Добавление базы данных
Прежде чем продолжить, убедитесь, что у вас установлен MongoDB или перейдите к Страница установки Mongodb Чтобы установить MongoDB.
Чтобы избежать потери данных, вы собираетесь переписать логику приложения, чтобы использовать базу данных MongoDB. Позже в посте вы развернете базу данных в вашем пространстве имен Okteto, но сначала давайте запустим ее локально, чтобы убедиться, что код работает отлично.
Начните с установки Pimongo
, драйвер MongoDB для приложения Python, Python-Decouple
Для чтения секретов среды и обновить Требования.txt
файл:
(venv)$ pip install pymongo
Обновите свой Требования.txt
файл:
... pymongo python-decouple
В API Папка, создайте новый файл, Database.py
, где вы напишите функции базы данных CRUD.
Начните с импорта МОГОКЛИЕНТ
, ObjectId
и конфигурация
:
from pymongo import MongoClient from bson import ObjectId from decouple import config
Mongoclient отвечает за соединение из нашего приложения к базе данных, ObjectId, с другой стороны, используется для передачи id
Значения в MongoDB должным образом и конфигурация
отвечает за чтение секретов приложения от .env
файлы
Далее определите сведения об соединении, базе данных и базе данных:
connection_details = config("DB_HOST") client = MongoClient(connection_details) database = client.recipes recipe_collection = database.get_collection('recipes_collection')
На первой строке выше вы используете Декупль
Библиотека для чтения переменной среды Db_host
. Создать .env
Файл в корневой папке, содержащей деталь подключения:
DB_HOST=mongodb://localhost:27017
Документы в MongoDB хранятся в формате JSON и _id
в ObjectId
формат. Напишите функцию, чтобы анализировать результат по запросу:
def parse_recipe_data(recipe) -> dict: return { "id": str(recipe["_id"]), "name": recipe["name"], "ingredients": recipe["ingredients"] }
CRUD функции
Следующим шагом является написание функций, ответственных за сохранение, удаление, обновление и удаление рецептов. Начните с реализации save_recipe
:
def save_recipe(recipe_data: dict) -> dict: recipe = recipe_collection.insert_one(recipe_data).inserted_id return { "id": str(recipe) }
Приведенная выше функция вставляет данные рецепта в базу данных и возвращает недавно созданный идентификатор рецепта.
Далее функция получения одного рецепта и всех рецептов из базы данных:
def get_single_recipe(id: str) -> dict: recipe = recipe_collection.find_one({"_id": ObjectId(id)}) if recipe: return parse_recipe_data(recipe) def get_all_recipes() -> list: recipes = [] for recipe in recipe_collection.find(): recipes.append(parse_recipe_data(recipe)) return recipes
Первая функция выше возвращает один рецепт, идентификатор которого соответствует предоставленному и сообщению об ошибке, если он не существует, в то время как вторая функция возвращает все содержащиеся рецепты в базе данных.
Далее напишите update_recipe_data
Функция ответственности за обновление данных рецепта:
def update_recipe_data(id: str, data: dict): recipe = recipe_collection.find_one({"_id": ObjectId(id)}) if recipe: recipe_collection.update_one({"_id": ObjectId(id)}, {"$set": data}) return True
Наконец, напишите функцию для удаления рецепта:
def remove_recipe(id: str): recipe = recipe_collection.find_one({"_id": ObjectId(id)}) if recipe: recipe_collection.delete_one({"_id": ObjectId(id)}) return True
С помощью функций CRUD базы данных замените содержание app/api.py
с:
from fastapi import FastAPI, Body from fastapi.encoders import jsonable_encoder from app.model import RecipeSchema, UpdateRecipeSchema from app.database import save_recipe, get_all_recipes, get_single_recipe, update_recipe_data, remove_recipe app = FastAPI() @app.get("/", tags=["Root"]) def get_root() -> dict: return { "message": "Welcome to the okteto's app.", } @app.get("/recipe", tags=["Recipe"]) def get_recipes() -> dict: recipes = get_all_recipes() return { "data": recipes } @app.get("/recipe/{id}", tags=["Recipe"]) def get_recipe(id: str) -> dict: recipe = get_single_recipe(id) if recipe: return { "data": recipe } return { "error": "No such recipe with ID {} exist".format(id) } @app.post("/recipe", tags=["Recipe"]) def add_recipe(recipe: RecipeSchema = Body(...)) -> dict: new_recipe = save_recipe(recipe.dict()) return new_recipe @app.put("/recipe", tags=["Recipe"]) def update_recipe(id: str, recipe_data: UpdateRecipeSchema) -> dict: if not get_single_recipe(id): return { "error": "No such recipe exist" } update_recipe_data(id, recipe_data.dict()) return { "message": "Recipe updated successfully." } @app.delete("/recipe/{id}", tags=["Recipe"]) def delete_recipe(id: str) -> dict: if not get_single_recipe(id): return { "error": "Invalid ID passed" } remove_recipe(id) return { "message": "Recipe deleted successfully." }
Обновите api/model.py
Удалив id
Поле в Рецептхема
модельный класс:
class RecipeSchema(BaseModel): name: str = Field(...) ingredients: List[str] = Field(...) class Config: schema_extra = { "example": { "name": "Donuts", "ingredients": ["Flour", "Milk", "Sugar", "Vegetable Oil"] } }
Тестирование базы данных
С подключением к базе данных запустите монгод
сервер, чтобы разрешить взаимодействие с базой данных:
mongod --port 27017
Далее, протестируйте маршрут почты:
(venv)$ curl -X POST http://localhost:8080/recipe -d \ '{"name": "Donut", "ingredients": ["Flour", "Milk", "Butter"]}' \ -H 'Content-Type: application/json'
Ответ:
{ "id": "601fdcd82fbbf462d33a6e34" }
Проверьте маршруты получить:
- Вернуть все рецепты
(venv)$ curl -X GET http://localhost:8080/recipe/2 -H 'Content-Type: application/json'
Ответ:
{ "data": [ { "id": "601fdcd82fbbf462d33a6e34", "name": "Donut", "ingredients": [ "Flour", "Milk", "Butter" ] } ] }
- Вернуть один рецепт
(venv)$ curl -X GET http://localhost:8080/recipe/601fdcd82fbbf462d33a6e34 -H 'Content-Type: application/json'
Ответ:
{ "data": { "id": "601fdcd82fbbf462d33a6e34", "name": "Donut", "ingredients": [ "Flour", "Milk", "Butter" ] } }
Проверьте маршрут обновления:
(venv)$ curl -X PUT "http://0.0.0.0:8080/recipe?id=601fdcd82fbbf462d33a6e34" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\":\"Buns\",\"ingredients\":[\"Flour\",\"Milk\",\"Sugar\",\"Vegetable Oil\"]}"
Ответ:
{ "message": "Recipe updated successfully." }
Наконец, проверьте маршрут удаления:
(venv)$ curl -X DELETE "http://0.0.0.0:8080/recipe/601fdcd82fbbf462d33a6e34" -H "accept: application/json"
Ответ:
{ "message": "Recipe deleted successfully." }
Перераспределение в Октето
Okteto облегчает напряжение развертывания и последующего перераспределения, позволяя нам обновлять и обновлять существующие приложения из файла стека. В предыдущем посте мы создали манифест стека Okteto для развертывания нашего сервиса Fastapi. Теперь мы собираемся обновить его, также включают mongodb
экземпляр как часть развертывания:
name: fastapi-crud services: fastapi: public: true image: okteto.dev/fastapi-crud:latest build: . replicas: 1 ports: - 8080 resources: cpu: 100m memory: 128Mi mongodb: image: bitnami/mongodb:latest ports: - 27017 resources: cpu: 100m memory: 128Mi volumes: - /bitnami/mongodb
В приведенном выше коде вы добавили другую службу, Mongodb
, чтобы разместить контейнер MongoDB от Bitnami. Он настроен на разоблачение порта по умолчанию MongoDB 27017 выставлен. Этот контейнер будет доступен только в вашем пространстве имен, и он настроен с постоянным томом /bitnami/mongodb
Чтобы гарантировать, что данные могут быть получены при перезапуске приложения.
Под FASTAPI
Сервис, добавьте заголовок среды, содержащую Db_host
Файл базы данных читается, используя Декупль
библиотека:
environment: - DB_HOST=mongodb://mongodb:27017 - secret=dev
С обновлением файла стека, разверните его, используя команду:
(venv)$ okteto stack deploy --build
Войдите в свой Приборная панель Okteto Анкет Обратите внимание, что ваше заявление теперь включает экземпляр MongoDB вместе с вашим заявлением:
Проверьте Рецепт
Маршрут, заменив DeployedApp
Из предыдущих запросов с помощью URL -адреса приложения живого приложения. Из вашего терминала запустите команду:
(venv)$ curl -X POST "https://fastapi-youngestdev.cloud.okteto.net/recipe" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"name\":\"Donuts\",\"ingredients\":[\"Flour\",\"Milk\",\"Sugar\",\"Vegetable Oil\"]}"
Отправленный ответ:
{ "id": "601fe6deaa1a27fbcb9a60fb" }
Совершение изменений в git
С помощью подтвержденных и проверенных изменений совершите все изменения в применении в филиал:
git add . git commit -m "Added MongoDB to the recipe application"
Протолкнуть совершенные изменения:
git push -u origin mongo-crud
Вывод
В этой статье вы изменили свою службу FastAPI, чтобы использовать реальную базу данных. Затем вы добавили службу базы данных в свой Октето Стек Манифест и развернул изменения с одной командой. Наконец, вы проверили изменения в конце концов, гарантируя, что они работают, как и ожидалось. Окончательная версия кода доступна На нашем репозитории GitHub Анкет
Создать Ваша бесплатная учетная запись Okteto Сегодня и начните разрабатывать новое приложение одним щелчком.
Оригинал: “https://dev.to/okteto/adding-a-database-to-your-application-using-okteto-stacks-5b79”