Operational Notes and Troubleshooting – Database Initialization and Persistence
A reliable database layer underpins the library REST API. This section explains how the SQLite file and tables are initialized, how persistence works, and how to troubleshoot common issues.
Database Configuration Overview
All database settings live in app.py. Flask-SQLAlchemy uses these keys to connect and manage models.
| Config Key | Purpose |
|---|---|
| SQLALCHEMY_DATABASE_URI | URI for SQLite file: sqlite:///data.db. |
| SQLALCHEMY_TRACK_MODIFICATIONS | Enable SQLAlchemy event notifications (set to True). |
| PROPAGATE_EXCEPTIONS | Allow exceptions to bubble to Flask’s error handlers. |
| secret_key | Used by Flask-JWT to sign and verify JSON Web Tokens. |
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['PROPAGATE_EXCEPTIONS'] = True
app.secret_key = 'SapanCrackle'
SQLite File – data.db Creation
The SQLite file data.db is created automatically:
- 📂 Location: Application root directory.
- 🔄 Trigger: On first HTTP request, via
create_tables(). - 💾 Persistence: Data persists between app restarts until you delete the file.
Table Creation Lifecycle
Flask-SQLAlchemy does not include migrations. Instead, tables are created lazily before handling any request.
@app.before_first_request
def create_tables():
db.create_all()
- Decorated with
@app.before_first_requestto run once - Calls
db.create_all(), inspecting alldb.Modelsubclasses to generate tables.
if __name__ == '__main__':
from db import db
db.init_app(app)
app.run(port=5000, debug=True)
db.init_app(app)binds SQLAlchemy to the Flask app.
Schema Evolution and Manual Migrations
No migration tool (e.g., Alembic) is included. When you add, remove, or modify model fields:
{
"title": "Schema Changes",
"content": "Delete `data.db` and restart the app to recreate tables after changing models."
}
- 🔄 Deleting
data.dbforces a clean schema build. - 🚫 Any existing data will be lost. Backup before deleting.
Lifecycle Flowchart
flowchart TD
A[App Start] --> B[db.init_app(app)]
B --> C[Ready to Serve]
C --> D{First HTTP Request?}
D -->|Yes| E[create_tables()]
E --> F[db.create_all()]
F --> C
D -->|No| C
C --> G[Handle Request]
🐞 Troubleshooting Common Issues
-
Missing Tables
Ensure the first request reaches the app. Check logs fordb.create_all()errors. -
Stale Schema
When models change, old tables persist. Deletedata.dbto rebuild. -
Permission Denied
Verify write permissions on the project directory. -
Database Locked
Avoid multiple concurrent writes. Close long-running sessions. -
Unintended Data Loss
Backupdata.dbbefore schema resets.
Best Practices
-
📦 .gitignore
Excludedata.dbfrom version control to avoid merge conflicts. -
🔒 Secure Secret Key
Do not hard-codesecret_keyin production. Use environment variables. -
🛠️ Local vs Production
Use lightweight SQLite locally; switch to a robust RDBMS for production. -
📝 Backups
Regularly dump or copydata.dbbefore destructive operations. -
🏷️ Environment Config
Centralize database URIs and credentials via a config file or environment variables.
By understanding how the SQLite file and tables are managed, you can confidently operate, evolve, and troubleshoot the library REST API’s persistence layer.