
In the previous article, we built our AI Haiku Generator web app using Python Flask in the backend. And HTML, CSS, and Javascript in the frontend. Now we will look at how we can add a database to the stack.
Let's say we want to store all the haiku's that are being generated in a database; we have a couple of options. Generally speaking, there are two types of databases, SQL and NoSQL. Both serve different purposes.
SQL databases are like well-organized libraries, where data is neatly stored in tables with strict rules—great for structured data and complex queries. NoSQL, on the other hand, is like a messy but flexible notebook, allowing you to jot things down without a fixed format—perfect for handling large, dynamic, and unstructured data. The choice depends on whether you prefer order or adaptability.
For our project, we will go ahead with the SQL database. Herein, we again have many options like MySQL and PostgreSQL. Those require setting up from our side, so for the sake of simplicity, we use another database called SQLite.
SQLite is like a portable notebook for your data—lightweight, serverless, and perfect for small projects where simplicity beats complexity.

We will start by opening our project in an editor. And then activating the virtual environment.
source env/bin/activate
Now that we have our virtual environment activated, we can install the needed package.
pip install flask-sqlalchemy
Once flask-sqlalchemy is installed, run the pip freeze command to lock the installed package and add it to requirements.txt.
pip freeze > requirements.txt
We install flask-sqlalchemy because it makes working with databases in Flask simple and intuitive. Instead of writing raw SQL queries, we get a Pythonic way to define, query, and manage our data with ease.
Okay, so that was all with the setup; now let's dive into some coding.
from flask import Flask, jsonify, render_template, request
from flask_sqlalchemy import SQLAlchemy
import google.generativeai as genai
from dotenv import load_dotenv
import os
load_dotenv()
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
genai.configure(api_key=GEMINI_API_KEY)
model = genai.GenerativeModel("gemini-1.5-flash")
app = Flask(__name__)
# Database initialization
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///haikus.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
Our main.py now looks like this. We import SQLAlchemy from flask_sqlalchemy package. Did our database initialization by defining the database path.
The first line tells Flask to use an SQLite database named haikus.db, creating it in the same folder if it doesn’t exist. The second line turns off unnecessary change tracking to keep things efficient.
db = SQLAlchemy(app)
class Haiku(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.Text, nullable=False)
def __repr__(self):
return f'<Haiku {self.id}>'
Under the DB initialization, we will create our Haiku model for storing our beautifully generated haikus.
This class defines a Haiku model using SQLAlchemy, with an auto-incrementing id as its primary key. The text field is required, and it stores the haiku content as text. The __repr__ method provides a readable string representation of the object, showing the haiku’s unique id when printed.
Now that we have our model ready to go. Let's add the code for the creation of tables underneath the model.
# Create the tables in the database
with app.app_context():
db.create_all()
db.create_all() ensures the database tables are created after the model is defined.

On running the web app using the command python main.py, we can see a new folder called instance is created. And there is a new file called haikus.db inside; that is our database ready for action.
Now we will move to the generate-haiku route.
@app.route("/generate-haiku", methods=['POST'])
def generate_haiku():
data = request.get_json() # Get JSON data from the request
theme = data.get('theme', None) # Access the 'theme' key from the JSON data
response = model.generate_content(f"You are an expert haiku poet who is in love with nature. Write me a haiku about {theme}")
haiku_text = response.text
# Save the haiku to the database
new_haiku = Haiku(text=haiku_text)
db.session.add(new_haiku)
db.session.commit()
return jsonify({"haiku": response.text})
Our code will now look as follows. We are extracting the text from the response and storing it in a variable called haiku_text. Then we call the Haiku model class and pass the haiku_text to the text field of the class.
Then we call db.session.add() to store the newly created haiku—new_haiku to the database. And then we commit the change to the DB.
Now we test if the generated haikus are being added to the database by running the server. And submitting a theme.
python main.py

I visited our web app, gave petals as the theme, and clicked Submit. The haiku is generated successfully, so we don't have any errors.
Go back to VS Code and install the extension Database Client.

It will give a visual tool for checking our haikus.db. Once the extension is installed, open the haikus.db file to view our generated haikus stored in the database.

Let's generate a few more.

Maybe we should store the theme along with the generated haiku. Let's add another column named theme.
If our database was of type NoSQL, we could have just inserted the theme value alongside the text. But because we are using an SQL database, any structural change will require adjusting the existing tables via migration or dropping the table and creating it from scratch.
class Haiku(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.Text, nullable=False)
theme = db.Column(db.String(255), nullable=False)
def __repr__(self):
return f'<Haiku {self.id}>'
# Create the tables in the database
with app.app_context():
db.drop_all() # Drops all tables
db.create_all()
First, update the Haiku model class to have the column field theme. Which is of type string and will have a max character of 255.
Add the db.drop_all() to the app.app_context(). When the app restarts, all our data will be deleted. Comment out the db.drop_all() to ensure we don't lose further data.

We see it in our Database Client extension on clicking the refresh icon. That all our generated haiku's are gone. And the columns now have an additional field of theme.
Let's now update our /generate-haiku route to also add in the user entered theme when calling the Haiku model class.
@app.route("/generate-haiku", methods=['POST'])
def generate_haiku():
data = request.get_json() # Get JSON data from the request
theme = data.get('theme', None) # Access the 'theme' key from the JSON data
response = model.generate_content(f"You are an expert haiku poet who is in love with nature. Write me a haiku about {theme}")
haiku_text = response.text
# Save the haiku to the database
new_haiku = Haiku(text=haiku_text, theme=theme)
db.session.add(new_haiku)
db.session.commit()
return jsonify({"haiku": response.text})
Now run the web app again and submit a few themes. Then we will check back our database to see the new entries.

All haiku's generated now will be stored along with their theme in our database.
What if we could also know who created these? In the next article, we will add user authentication so only logged-in user's can generate haikus. And for each generated haiku, we will also store the user's name.
Note: You can find the full source code at the GitHub Repo.

Write a comment ...