How Do I Upload Mongo Database to Github

Adding A Database to Your Application Using Okteto Stacks

Temporary in-app databases are not platonic for web applications. Whatever unfortunate event such as an sharp shutdown or restarting of the awarding will lead to the total loss of stored data.

This is the tertiary mail service in our series on how to develop a fastAPI application with Okteto. In the previous posts, you learned how to deploy applications direct from your panel using Okteto Stacks and how to deploy it directly from Okteto's UI.

In this tutorial, you will be adding a database to store better your application data, and so you will deploy the updated version to your Okteto namespace directly from your command line.

Initial Setup

Start by creating a fork of the application from GitHub and then clone it locally.

                          git              clone https://github.com/okteto/fastapi-crud                      

In your local clone, set it upward using the following commands:

            $              cd              fastapi-crud $ python3 -thou venv venv              &&              source              venv/bin/activate              (venv)$ pip              install              -r requirements.txt                      

Verify that the setup is complete by running:

Subsequently verifying the installation, update the DOCKERHUBUSERNAME variable in your stack file to okteto.dev. Deploy the application with the command:

                          (venv)$ okteto stack deploy --build                      

Creating A New Branch

For this article, we will create a new branch. This is to enable you to differentiate the first post in the series from this.

From your console, run the control:

                          git              checkout -b mongo-crud                      

The command higher up creates a new branch mongo-crud with the origin pointing to main.

Adding A Database

Before proceeding, verify that you have MongoDB installed or go along to the MongoDB's Installation folio to install MongoDB.

To avoid information loss, you're going to rewrite the application logic to use a MongoDB database. Later on in the mail you'll deploy the database in your Okteto namespace, but first, let'south run it locally to verify that the code works perfectly.

Start past installing pymongo, a MongoDB driver for Python application, python-decouple for reading surround secrets and update the requirements.txt file:

                          (venv)$ pip              install              pymongo                      

Update your requirements.txt file:

            ... pymongo python-decouple                      

In the api folder, create a new file, database.py, where you'll write the database Crud operations' functions.

Outset by importing MongoClient, ObjectID and config:

                          from              pymongo              import              MongoClient              from              bson              import              ObjectId              from              decouple              import              config                      

MongoClient is responsible for the connection from our awarding to the database, ObjectId, on the other manus, is used to pass id values in MongoDB properly, and config is responsible for reading application secrets from .env files.

Next, ascertain the connectedness, database and database collection details:

            connection_details              =              config(              "DB_HOST"              )              client              =              MongoClient(connection_details)              database              =              client.recipes  recipe_collection              =              database.get_collection(              'recipes_collection'              )                      

On the outset line in a higher place, you are using the decouple library to read the environment variable DB_HOST. Create a .env file in the root folder containing the connection detail:

            DB_HOST=mongodb://localhost:27017                      

Documents in MongoDB are stored in JSON format and the _id in ObjectId format. Write a office to parse the outcome from a query:

                          def              parse_recipe_data              (recipe)              -              >              dict              :              return              {              "id"              :              str              (recipe[              "_id"              ]              )              ,              "name"              :              recipe[              "proper noun"              ]              ,              "ingredients"              :              recipe[              "ingredients"              ]              }                      

CRUD functions

The next step is to write the functions responsible for saving, removing, updating and deleting recipes. Start by implementing the save_recipe:

                          def              save_recipe              (recipe_data:              dict              )              -              >              dict              :              recipe              =              recipe_collection.insert_one(recipe_data)              .inserted_id              return              {              "id"              :              str              (recipe)              }                      

The function above inserts the recipe data into the database and returns the newly created recipe's ID.

Next, the function for retrieving a unmarried recipe and all the recipes from the database:

                          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                      

The outset function higher up returns a unmarried recipe whose ID matches the supplied one and an error message if it doesn't be, while the second part returns all the contained recipes in the database.

Next, write the update_recipe_data office responsible for updating 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              Truthful                      

Lastly, write the function for deleting a recipe:

                          def              remove_recipe              (              id              :              str              )              :              recipe              =              recipe_collection.find_one(              {              "_id"              :              ObjectId(              id              )              }              )              if              recipe:              recipe_collection.delete_one(              {              "_id"              :              ObjectId(              id              )              }              )              return              True                      

With the database CRUD functions in place, replace the content of app/api.py with:

                          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.become              (              "/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:              render              {              "data"              :              recipe              }              return              {              "error"              :              "No such recipe with ID {} exist"              .              format              (              id              )              }              @app.post              (              "/recipe"              ,              tags=              [              "Recipe"              ]              )              def              add_recipe              (recipe:              RecipeSchema              =              Trunk(              .              .              .              )              )              -              >              dict              :              new_recipe              =              save_recipe(recipe.              dict              (              )              )              render              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              (              )              )              render              {              "bulletin"              :              "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."              }                      

Update the api/model.py by removing the id field in the RecipeSchema model class:

                          course              RecipeSchema              (BaseModel)              :              name:              str              =              Field(              .              .              .              )              ingredients:              List[              str              ]              =              Field(              .              .              .              )              class              Config              :              schema_extra              =              {              "example"              :              {              "proper noun"              :              "Donuts"              ,              "ingredients"              :              [              "Flour"              ,              "Milk"              ,              "Sugar"              ,              "Vegetable Oil"              ]              }              }                      

Testing The Database

With the database connection in identify, get-go a mongod server to permit interactions with the database:

Next, test the POST route:

                          (venv)$              curl              -Ten POST http://localhost:8080/recipe -d              \              '{"name": "Donut", "ingredients": ["Flour", "Milk", "Butter"]}'              \              -H              'Content-Type: application/json'                      

Response:

                          {              "id"              :              "601fdcd82fbbf462d33a6e34"              }                      

Test the GET routes:

  1. Return all recipes
                          (venv)$              roll              -X Become http://localhost:8080/recipe/2 -H              'Content-Type: awarding/json'                      

Response:

                          {              "data"              :              [              {              "id"              :              "601fdcd82fbbf462d33a6e34"              ,              "name"              :              "Donut"              ,              "ingredients"              :              [              "Flour"              ,              "Milk"              ,              "Butter"              ]              }              ]              }                      
  1. Return a unmarried recipe
                          (venv)$              curl              -X Go http://localhost:8080/recipe/601fdcd82fbbf462d33a6e34 -H              'Content-Type: application/json'                      

Response:

                          {              "data"              :              {              "id"              :              "601fdcd82fbbf462d33a6e34"              ,              "name"              :              "Donut"              ,              "ingredients"              :              [              "Flour"              ,              "Milk"              ,              "Butter"              ]              }              }                      

Test the UPDATE route:

                          (venv)$              curl              -X PUT              "http://0.0.0.0:8080/recipe?id=601fdcd82fbbf462d33a6e34"              -H              "have: application/json"              -H              "Content-Type: awarding/json"              -d              "{\"proper noun\":\"Buns\",\"ingredients\":[\"Flour\",\"Milk\",\"Sugar\",\"Vegetable Oil\"]}"                      

Response:

                          {              "message"              :              "Recipe updated successfully."              }                      

Lastly, test the DELETE route:

                          (venv)$              gyre              -X DELETE              "http://0.0.0.0:8080/recipe/601fdcd82fbbf462d33a6e34"              -H              "accept: awarding/json"                      

Response:

                          {              "bulletin"              :              "Recipe deleted successfully."              }                      

Redeploying to Okteto

Okteto eases the stress of deployment and subsequent redeployment past allowing us to update and upgrade existing applications from the stack file. In the previous mail service, nosotros created an okteto stack manifest to deploy our fastAPI service. We are now going to update it too include a mongodb example as part of the deployment:

                          services              :              fastapi              :              build              :              .              ports              :              -              8080:              8080              environs              :              -              DB_HOST=mongodb://mongodb:              27017              -              secret=dev              mongodb              :              image              :              bitnami/mongodb:latest              ports              :              -              27017              volumes              :              -              data:/bitnami/mongodb              volumes              :              data              :                      

In the code above, you added some other service, mongodb, to business firm a MongoDB container from bitnami. It'southward configured to expose MongoDB'southward default port 27017 is exposed. This container volition but be attainable from your namespace, and it's configured with a persistent volume /bitnami/mongodb to ensure that data can exist retrieved when the awarding restarts.

Under the fastapi service, add an surround heading containing the DB_HOST the database file reads using the decouple library:

                          environment              :              -              DB_HOST=mongodb://mongodb:              27017              -              secret=dev                      

With the stack file updated, deploy information technology using the command:

                          (venv)$ okteto stack deploy --build                      

Log on to your Okteto Dashboard. Notice that your awarding now includes an example of MongoDB alongside your application:

Dashboard

Examination the recipe road by replacing deployedapp from previous requests with the live awarding URL. From your terminal, run the command:

                          (venv)$              curl              -X Postal service              "https://fastapi-youngestdev.cloud.okteto.internet/recipe"              -H              "accept: application/json"              -H              "Content-Type: application/json"              -d              "{\"proper name\":\"Donuts\",\"ingredients\":[\"Flour\",\"Milk\",\"Carbohydrate\",\"Vegetable Oil\"]}"                      

The response sent out is:

                          {              "id"              :              "601fe6deaa1a27fbcb9a60fb"              }                      

Committing Changes to Git

With the changes confirmed and tested, commit all the changes in the application to the branch:

                          git              add together              .              git              commit -thousand              "Added MongoDB to the recipe awarding"                      

Push the committed changes:

                          git              push -u origin mongo-crud                      

Conclusion

In this article, y'all modified your fastAPI service to employ a real database. You then added the database service to your okteto stack manifest and deployed the changes with one control. Finally, you tested the changes end to cease, ensuring that they work as expected. The final version of the code is available on our GitHub repository.

Create your gratuitous Okteto account today and begin developing your new application with one click.

mooreusbodleacter.blogspot.com

Source: https://okteto.com/blog/adding-a-database-to-your-app-using-okteto-stack/

0 Response to "How Do I Upload Mongo Database to Github"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel