You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-- SQL - Structured Query Language-- Used to manage and query relational databases-- CRUD Operations:-- Create (INSERT)-- Read (SELECT)-- Update (UPDATE)-- Delete (DELETE)
Database Concepts
-- Database: Collection of tables-- Table: Collection of rows (records)-- Row: Single record with multiple columns-- Column: Single field/attribute-- Example:-- Database: school-- Table: students-- Columns: id, name, age, grade-- Row: (1, 'Wilson', 20, 'A')
DDL - Data Definition
Create Table
-- CREATE TABLE - Define new table structureCREATETABLEstudents (
id INTEGERPRIMARY KEY,
first_name TEXTNOT NULL,
last_name TEXTNOT NULL,
email TEXT UNIQUE NOT NULL,
age INTEGER,
grade TEXT,
enrolled_date DATE DEFAULT CURRENT_DATE
);
-- With constraintsCREATETABLEusers (
id INTEGERPRIMARY KEY AUTOINCREMENT,
username TEXTNOT NULL UNIQUE,
email TEXTNOT NULL UNIQUE,
password TEXTNOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1,
CHECK (age >=18)
);
Alter Table
-- ALTER TABLE - Modify existing table-- Add columnALTERTABLE students
ADD COLUMN phone TEXT;
-- Drop columnALTERTABLE students
DROP COLUMN phone;
-- Rename columnALTERTABLE students
RENAME COLUMN grade TO gpa;
-- Rename tableALTERTABLE students
RENAME TO enrollments;
Drop Table
-- DROP TABLE - Delete entire tableDROPTABLE students;
-- Drop if exists (safer)DROPTABLE IF EXISTS students;
Data Types
-- Common SQLite data types:INTEGER-- Whole numbers: 1, 42, -100REAL-- Decimal numbers: 3.14, 99.99TEXT-- Strings: 'Hello', 'Wilson@email.com'
BLOB -- Binary data: images, filesBOOLEAN-- True/False (stored as 0/1)DATE-- Dates: '2024-01-15'
DATETIME -- Date and time: '2024-01-15 14:30:00'
Constraints
-- Constraints - Rules for data integrityCREATETABLEproducts (
id INTEGERPRIMARY KEY, -- Unique identifier
name TEXTNOT NULL, -- Cannot be NULL
price REALNOT NULLCHECK (price >0), -- Must be positive
sku TEXT UNIQUE, -- Must be unique
category_id INTEGER,
FOREIGN KEY (category_id) REFERENCES categories(id) -- Must exist in categories
);
DML - Data Manipulation
INSERT - Add Data
-- Insert single rowINSERT INTO students (first_name, last_name, email, age)
VALUES ('Wilson', 'Johnson', 'Wilson@email.com', 20);
-- Insert multiple rowsINSERT INTO students (first_name, last_name, email, age)
VALUES
('Bob', 'Smith', 'bob@email.com', 22),
('Charlie', 'Brown', 'charlie@email.com', 21),
('Diana', 'Prince', 'diana@email.com', 23);
-- Insert with all columnsINSERT INTO students
VALUES (1, 'Eve', 'Wilson', 'eve@email.com', 19, 'A', '2024-01-15');
SELECT - Retrieve Data
-- Select all columnsSELECT*FROM students;
-- Select specific columnsSELECT first_name, last_name, email FROM students;
-- Select with aliasSELECT first_name AS"First Name",
last_name AS"Last Name"FROM students;
-- Select distinct valuesSELECT DISTINCT grade FROM students;
-- Select with calculationSELECT first_name, age, age +1AS"Next Year Age"FROM students;
UPDATE - Modify Data
-- Update single rowUPDATE students
SET grade ='A+'WHERE id =1;
-- Update multiple columnsUPDATE students
SET grade ='B', age =21WHERE first_name ='Wilson';
-- Update all rows (careful!)UPDATE students
SET is_active =1;
-- Update with calculationUPDATE products
SET price = price *1.1-- 10% increaseWHERE category ='Electronics';
DELETE - Remove Data
-- Delete specific rowsDELETEFROM students
WHERE id =1;
-- Delete with conditionDELETEFROM students
WHERE age <18;
-- Delete all rows (careful!)DELETEFROM students;
-- Better: use TRUNCATE (if supported)
TRUNCATE TABLE students;
SQL Queries
WHERE Clause
-- Filter results with conditions-- EqualSELECT*FROM students WHERE grade ='A';
-- Not equalSELECT*FROM students WHERE grade !='F';
-- ComparisonSELECT*FROM students WHERE age >=21;
-- Multiple conditions (AND)SELECT*FROM students
WHERE grade ='A'AND age >=20;
-- Multiple conditions (OR)SELECT*FROM students
WHERE grade ='A'OR grade ='B';
-- IN operatorSELECT*FROM students
WHERE grade IN ('A', 'B', 'C');
-- BETWEENSELECT*FROM students
WHERE age BETWEEN 18AND22;
-- LIKE (pattern matching)SELECT*FROM students
WHERE email LIKE'%@gmail.com';
-- IS NULLSELECT*FROM students
WHERE phone IS NULL;
ORDER BY
-- Sort results-- Ascending (default)SELECT*FROM students
ORDER BY last_name;
-- DescendingSELECT*FROM students
ORDER BY age DESC;
-- Multiple columnsSELECT*FROM students
ORDER BY grade ASC, age DESC;
LIMIT and OFFSET
-- Limit number of resultsSELECT*FROM students
LIMIT10;
-- PaginationSELECT*FROM students
LIMIT10 OFFSET 20; -- Skip first 20, get next 10-- Top 5 oldest studentsSELECT*FROM students
ORDER BY age DESCLIMIT5;
Aggregate Functions
-- COUNT - Count rowsSELECTCOUNT(*) FROM students;
SELECTCOUNT(*) FROM students WHERE grade ='A';
-- SUM - Sum valuesSELECTSUM(price) FROM products;
-- AVG - AverageSELECTAVG(age) FROM students;
-- MIN/MAXSELECTMIN(age), MAX(age) FROM students;
-- Multiple aggregatesSELECTCOUNT(*) as total_students,
AVG(age) as average_age,
MIN(age) as youngest,
MAX(age) as oldest
FROM students;
GROUP BY
-- Group and aggregate-- Count students per gradeSELECT grade, COUNT(*) as student_count
FROM students
GROUP BY grade;
-- Average age per gradeSELECT grade, AVG(age) as avg_age
FROM students
GROUP BY grade;
-- HAVING - Filter groups (like WHERE for groups)SELECT grade, COUNT(*) as count
FROM students
GROUP BY grade
HAVINGCOUNT(*) >5;
JOINs
-- INNER JOIN - Rows with matches in both tablesSELECTstudents.name, courses.course_nameFROM students
INNER JOIN enrollments ONstudents.id=enrollments.student_idINNER JOIN courses ONenrollments.course_id=courses.id;
-- LEFT JOIN - All from left, matches from rightSELECTstudents.name, courses.course_nameFROM students
LEFT JOIN enrollments ONstudents.id=enrollments.student_id;
-- Self JOIN - Join table to itselfSELECTe1.name, e2.nameas manager
FROM employees e1
LEFT JOIN employees e2 ONe1.manager_id=e2.id;
SQLAlchemy Setup
Installation
pip install sqlalchemy
Basic Setup
fromsqlalchemyimportcreate_enginefromsqlalchemy.ormimportdeclarative_base, sessionmaker# Create engine (connect to database)engine=create_engine('sqlite:///my_database.db', echo=True)
# echo=True shows SQL queries in console# Create base class for modelsBase=declarative_base()
# Create session factorySession=sessionmaker(bind=engine)
session=Session()
frommodelsimportUser, session# Create single usernew_user=User(
username='Wilson',
email='Wilson@example.com',
password='hashed_password'
)
# Add to sessionsession.add(new_user)
# Commit to databasesession.commit()
# Access ID after commitprint(new_user.id) # Auto-generated ID# Create multiple usersusers= [
User(username='bob', email='bob@example.com', password='pass123'),
User(username='charlie', email='charlie@example.com', password='pass456')
]
session.add_all(users)
session.commit()
Read (Query)
frommodelsimportUser, session# Get all usersall_users=session.query(User).all()
# Get first userfirst_user=session.query(User).first()
# Get by IDuser=session.get(User, 1) # User with id=1# Query with filterWilson=session.query(User).filter(User.username=='Wilson').first()
# Multiple filters (AND)user=session.query(User).filter(
User.username=='Wilson',
User.is_active==True
).first()
# OR conditionfromsqlalchemyimportor_users=session.query(User).filter(
or_(User.username=='Wilson', User.username=='bob')
).all()
# LIKE querygmail_users=session.query(User).filter(
User.email.like('%@gmail.com')
).all()
# IN queryusers=session.query(User).filter(
User.username.in_(['Wilson', 'bob', 'charlie'])
).all()
# Order byusers=session.query(User).order_by(User.username).all()
users=session.query(User).order_by(User.created_at.desc()).all()
# Limitusers=session.query(User).limit(10).all()
# Countcount=session.query(User).count()
# Get all pets owned by Wilsonpets=session.query(Pet).join(Owner).filter(Owner.name=='Wilson').all()
# Get all students enrolled in Python 101students=session.query(Student).join(
student_course
).join(Course).filter(Course.name=='Python 101').all()
# Count pets per ownerfromsqlalchemyimportfuncresults=session.query(
Owner.name,
func.count(Pet.id).label('pet_count')
).join(Pet).group_by(Owner.name).all()
# Subquery for average ageavg_age_subquery=session.query(func.avg(User.age)).scalar_subquery()
# Find users older than averageolder_users=session.query(User).filter(User.age>avg_age_subquery).all()
Best Practices
Session Management
# Use context manager for automatic cleanupfromcontextlibimportcontextmanager@contextmanagerdefget_session():
session=Session()
try:
yieldsessionsession.commit()
except:
session.rollback()
raisefinally:
session.close()
# Usagewithget_session() assession:
user=User(username='Wilson', email='Wilson@example.com')
session.add(user)
# Auto-commits and closes
# Eager loading (prevent N+1 queries)fromsqlalchemy.ormimportjoinedload# Load owner with pets in single queryowners=session.query(Owner).options(joinedload(Owner.pets)).all()
# Select only needed columnsusers=session.query(User.username, User.email).all()
# Use paginationpage=1per_page=20users=session.query(User).limit(per_page).offset((page-1) *per_page).all()