01_database_setup.py
SQL/python_examples/01_database_setup.py
"""
====================================================================
Lesson 1: Database Setup and Connection - Flask + SQLAlchemy ORM Examples
====================================================================
This module demonstrates how to connect to MySQL using Flask and SQLAlchemy ORM.
It covers:
1. Flask application setup with SQLAlchemy
2. Environment variable configuration for database credentials
3. Database connection and session management
4. Basic database operations using ORM
5. Error handling and connection management
6. Best practices for Flask-SQLAlchemy integration
Key Concepts:
- Flask: Lightweight web framework for Python
- SQLAlchemy ORM: Object-Relational Mapping for database operations
- Flask-SQLAlchemy: Flask extension that adds SQLAlchemy support
- Database models: Python classes that represent database tables
- Session management: Handling database transactions and connections
====================================================================
"""
# Import required libraries
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text, create_engine
from sqlalchemy.orm import sessionmaker
import os
from dotenv import load_dotenv
from datetime import datetime
# Load environment variables from .env file
load_dotenv()
# Initialize Flask application
app = Flask(__name__)
# Configure database connection
app.config['SQLALCHEMY_DATABASE_URI'] = (
f"mysql+pymysql://{os.getenv('DB_USER', 'student')}:"
f"{os.getenv('DB_PASSWORD', 'password123')}@"
f"{os.getenv('DB_HOST', 'localhost')}:"
f"{os.getenv('DB_PORT', 3306)}/"
f"{os.getenv('DB_NAME', 'learning_db')}"
)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
'pool_pre_ping': True,
'pool_recycle': 300,
'connect_args': {'charset': 'utf8mb4'}
}
# Initialize SQLAlchemy with Flask app
db = SQLAlchemy(app)
class DatabaseConnection:
"""
DatabaseConnection class handles all database connection operations using Flask-SQLAlchemy.
This class encapsulates database connection logic and provides methods
for common database operations like testing connections, creating databases,
and managing database sessions using ORM patterns.
Attributes:
app (Flask): Flask application instance
db (SQLAlchemy): SQLAlchemy database instance
"""
def __init__(self):
"""
Initialize database connection using Flask-SQLAlchemy.
Uses the Flask application context to manage database connections
and provides ORM-based database operations.
"""
self.app = app
self.db = db
def test_connection(self):
"""
Test basic connection to MySQL server using SQLAlchemy ORM.
This method verifies that we can successfully connect to the MySQL server
and execute a simple query using the ORM session.
Returns:
bool: True if connection successful, False otherwise
Raises:
Exception: If connection fails, prints error message and returns False
"""
try:
# Use Flask application context
with self.app.app_context():
# Test connection by executing a simple query
result = self.db.session.execute(text("SELECT VERSION()"))
version = result.fetchone()[0]
print(f"✅ Connected to MySQL version: {version}")
return True
except Exception as e:
print(f"❌ Connection failed: {e}")
return False
def show_databases(self):
"""
Display all available databases on the MySQL server.
This method connects to the MySQL server and executes the SHOW DATABASES
command to list all databases that the current user has access to.
Returns:
list: List of database names, empty list if error occurs
"""
try:
with self.app.app_context():
# Execute SHOW DATABASES command using ORM session
result = self.db.session.execute(text("SHOW DATABASES"))
# Extract database names from result set
databases = [row[0] for row in result.fetchall()]
# Display results in a user-friendly format
print("Available databases:")
for db_name in databases:
print(f" - {db_name}")
return databases
except Exception as e:
print(f"Error showing databases: {e}")
return []
def create_database(self, db_name):
"""
Create a new database with the specified name.
Args:
db_name (str): Name of the database to create
Returns:
bool: True if database created successfully, False otherwise
Notes:
- Uses IF NOT EXISTS to avoid errors if database already exists
- Commits the transaction to make the change permanent
"""
try:
with self.app.app_context():
# Execute CREATE DATABASE command with IF NOT EXISTS clause
self.db.session.execute(text(f"CREATE DATABASE IF NOT EXISTS {db_name}"))
# Commit the transaction to make the database creation permanent
self.db.session.commit()
print(f"✅ Database '{db_name}' created successfully")
return True
except Exception as e:
print(f"❌ Failed to create database: {e}")
self.db.session.rollback()
return False
def use_database(self, db_name):
"""
Switch the current session to use the specified database.
Args:
db_name (str): Name of the database to switch to
Returns:
str: Name of the current database if successful, None if failed
Notes:
- This is equivalent to the SQL command "USE database_name"
- Verifies the switch was successful by querying DATABASE()
"""
try:
with self.app.app_context():
# Execute USE command to switch to specified database
self.db.session.execute(text(f"USE {db_name}"))
# Verify the switch was successful by querying current database
result = self.db.session.execute(text("SELECT DATABASE()"))
current_db = result.fetchone()[0]
print(f"✅ Now using database: {current_db}")
return current_db
except Exception as e:
print(f"❌ Failed to use database: {e}")
return None
def show_tables(self):
"""
Display all tables in the current database.
This method shows all tables that exist in the currently selected database.
It's useful for exploring the database structure and verifying table creation.
Returns:
list: List of table names, empty list if error occurs
"""
try:
with self.app.app_context():
# Execute SHOW TABLES command
result = self.db.session.execute(text("SHOW TABLES"))
# Extract table names from result set
tables = [row[0] for row in result.fetchall()]
# Display results in a user-friendly format
print("Tables in current database:")
for table in tables:
print(f" - {table}")
return tables
except Exception as e:
print(f"Error showing tables: {e}")
return []
class SampleModel(db.Model):
"""
Sample database model to demonstrate SQLAlchemy ORM usage.
This model represents a simple table for demonstration purposes.
It shows how to define database models using SQLAlchemy ORM.
"""
__tablename__ = 'sample_table'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
description = db.Column(db.Text)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
def __repr__(self):
return f'<SampleModel {self.name}>'
def to_dict(self):
"""Convert model instance to dictionary"""
return {
'id': self.id,
'name': self.name,
'description': self.description,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None
}
class DatabaseOperations:
"""
DatabaseOperations class demonstrates ORM-based database operations.
This class shows how to perform CRUD operations using SQLAlchemy ORM
instead of raw SQL queries.
"""
def __init__(self):
"""Initialize with Flask app and database instance"""
self.app = app
self.db = db
def create_tables(self):
"""
Create all database tables using SQLAlchemy ORM.
This method creates all tables defined in the models.
Returns:
bool: True if tables created successfully, False otherwise
"""
try:
with self.app.app_context():
# Create all tables defined in models
self.db.create_all()
print("✅ All tables created successfully using ORM")
return True
except Exception as e:
print(f"❌ Failed to create tables: {e}")
return False
def insert_sample_data(self):
"""
Insert sample data using SQLAlchemy ORM.
This method demonstrates how to create and save model instances
using the ORM instead of raw SQL INSERT statements.
Returns:
bool: True if data inserted successfully, False otherwise
"""
try:
with self.app.app_context():
# Create sample model instances
sample1 = SampleModel(
name='Sample Record 1',
description='This is a sample record created using SQLAlchemy ORM'
)
sample2 = SampleModel(
name='Sample Record 2',
description='Another sample record demonstrating ORM usage'
)
# Add instances to session
self.db.session.add(sample1)
self.db.session.add(sample2)
# Commit the transaction
self.db.session.commit()
print("✅ Sample data inserted successfully using ORM")
return True
except Exception as e:
print(f"❌ Failed to insert sample data: {e}")
self.db.session.rollback()
return False
def query_sample_data(self):
"""
Query sample data using SQLAlchemy ORM.
This method demonstrates how to retrieve data using ORM queries
instead of raw SQL SELECT statements.
Returns:
list: List of sample records, empty list if error occurs
"""
try:
with self.app.app_context():
# Query all records using ORM
samples = SampleModel.query.all()
print("Sample records retrieved using ORM:")
for sample in samples:
print(f" - {sample}")
print(f" Dict: {sample.to_dict()}")
# Query with conditions
filtered_samples = SampleModel.query.filter(
SampleModel.name.like('%Record%')
).all()
print(f"\nFiltered records: {len(filtered_samples)} found")
return [sample.to_dict() for sample in samples]
except Exception as e:
print(f"❌ Failed to query sample data: {e}")
return []
def update_sample_data(self):
"""
Update sample data using SQLAlchemy ORM.
This method demonstrates how to update records using ORM
instead of raw SQL UPDATE statements.
Returns:
bool: True if update successful, False otherwise
"""
try:
with self.app.app_context():
# Find and update a record
sample = SampleModel.query.first()
if sample:
sample.description = "Updated description using SQLAlchemy ORM"
sample.updated_at = datetime.utcnow()
# Commit the changes
self.db.session.commit()
print(f"✅ Updated record: {sample}")
return True
else:
print("No records found to update")
return False
except Exception as e:
print(f"❌ Failed to update sample data: {e}")
self.db.session.rollback()
return False
def delete_sample_data(self):
"""
Delete sample data using SQLAlchemy ORM.
This method demonstrates how to delete records using ORM
instead of raw SQL DELETE statements.
Returns:
bool: True if deletion successful, False otherwise
"""
try:
with self.app.app_context():
# Find and delete a record
sample = SampleModel.query.filter(
SampleModel.name.like('%Record 2%')
).first()
if sample:
self.db.session.delete(sample)
self.db.session.commit()
print(f"✅ Deleted record: {sample}")
return True
else:
print("No records found to delete")
return False
except Exception as e:
print(f"❌ Failed to delete sample data: {e}")
self.db.session.rollback()
return False
def main():
"""
Main function to demonstrate database connection and ORM operations.
This function serves as a comprehensive example of how to:
1. Initialize a database connection using Flask-SQLAlchemy
2. Test connectivity to MySQL server
3. List available databases
4. Create a new database
5. Switch to a specific database
6. List tables in the current database
7. Perform CRUD operations using SQLAlchemy ORM
The function follows a logical progression that would be typical
in a real-world Flask application setup process.
"""
print("=== Flask + SQLAlchemy ORM Database Connection Demo ===\n")
# Initialize database connection object
db_connection = DatabaseConnection()
# Step 1: Test basic connection to MySQL server
print("1. Testing connection...")
if not db_connection.test_connection():
print("Please check your MySQL server and credentials")
return # Exit if connection fails
# Step 2: Display all available databases
print("\n2. Showing available databases...")
databases = db_connection.show_databases()
# Step 3: Create the learning database if it doesn't exist
print("\n3. Creating learning database...")
db_connection.create_database('learning_db')
# Step 4: Switch to the learning database
print("\n4. Switching to learning database...")
db_connection.use_database('learning_db')
# Step 5: Show tables in the current database
print("\n5. Showing tables in learning database...")
db_connection.show_tables()
# Step 6: Demonstrate ORM operations
print("\n6. Demonstrating SQLAlchemy ORM operations...")
db_operations = DatabaseOperations()
# Create tables using ORM
print("\n6a. Creating tables using ORM...")
db_operations.create_tables()
# Show tables again
print("\n6b. Showing tables after ORM creation...")
db_connection.show_tables()
# Insert sample data using ORM
print("\n6c. Inserting sample data using ORM...")
db_operations.insert_sample_data()
# Query sample data using ORM
print("\n6d. Querying sample data using ORM...")
db_operations.query_sample_data()
# Update sample data using ORM
print("\n6e. Updating sample data using ORM...")
db_operations.update_sample_data()
# Query updated data
print("\n6f. Querying updated data using ORM...")
db_operations.query_sample_data()
# Delete sample data using ORM
print("\n6g. Deleting sample data using ORM...")
db_operations.delete_sample_data()
# Final query
print("\n6h. Final query using ORM...")
db_operations.query_sample_data()
print("\n=== Flask + SQLAlchemy ORM Connection Demo Complete ===")
# Standard Python idiom for running the script
if __name__ == "__main__":
main()
関連記事
COM641_Task3_Solutions.sql
COM641_Task3_Solutions.sql — sql source code from the SQL learning materials (SQL/assignment/COM641_Task3_Solutions.sql).
記事を読む →exercise_01_basic_queries.sql
exercise_01_basic_queries.sql — sql source code from the SQL learning materials (SQL/exercises/exercise_01_basic_queries.sql).
記事を読む →exercise_02_joins.sql
exercise_02_joins.sql — sql source code from the SQL learning materials (SQL/exercises/exercise_02_joins.sql).
記事を読む →exercise_03_database_design.sql
exercise_03_database_design.sql — sql source code from the SQL learning materials (SQL/exercises/exercise_03_database_design.sql).
記事を読む →exercise_04_database_functions.sql
exercise_04_database_functions.sql — sql source code from the SQL learning materials (SQL/exercises/exercise_04_database_functions.sql).
記事を読む →02_create_database_tables.py
02_create_database_tables.py — python source code from the SQL learning materials (SQL/python_examples/02_create_database_tables.py).
記事を読む →