杰瑞科技汇

Python SQLAlchemy怎么用?

Of course! Let's dive deep into SQLAlchemy. It's one of the most powerful and popular ORMs (Object-Relational Mappers) for Python.

Python SQLAlchemy怎么用?-图1
(图片来源网络,侵删)

What is SQLAlchemy?

At its core, SQLAlchemy is a SQL Toolkit and Object-Relational Mapping library for Python.

This means it does two main things:

  1. Provides a set of tools to interact with databases using raw SQL in a Pythonic way. This is called the Core.
  2. Provides an Object-Relational Mapper (ORM) that allows you to interact with your database using Python classes and objects, instead of writing SQL queries directly. This is called the ORM.

The ORM is what most developers love about SQLAlchemy, as it makes database operations feel very natural in an object-oriented language like Python.


Why Use SQLAlchemy? (The Benefits)

  • Database Agnostic: Write your code once, and it can work with many different database backends (like PostgreSQL, MySQL, SQLite, Oracle) with minimal or no changes.
  • Security: It automatically handles parameterization, which protects against SQL injection attacks.
  • Pythonic: You work with Python objects and methods, not complex SQL strings.
  • Powerful & Flexible: You can start with simple ORM queries and drop down to write raw SQL whenever you need maximum performance or complex features.
  • Rich Ecosystem: It's well-integrated with other popular Python frameworks like Flask and FastAPI.

The Two Main Parts: Core vs. ORM

It's crucial to understand that SQLAlchemy has two distinct layers. You can use them together or separately.

Python SQLAlchemy怎么用?-图2
(图片来源网络,侵删)

SQLAlchemy Core (The "Toolkit")

This is the foundation. It's a schema-centric, SQL-expression-based way of talking to the database. You don't deal with Python classes yet; you deal with tables, columns, and SQL expressions.

  • Table: Represents a database table.
  • Column: Represents a column in a table.
  • select(): A function to build a SQL SELECT statement.
  • insert() / update() / delete(): Functions to build DML (Data Manipulation Language) statements.
  • Engine: The core interface to the database, responsible for managing the connection pool.
  • Connection: Represents a single DBAPI connection.
  • Session: (A bridge between Core and ORM) A "holding zone" for objects that have been loaded or associated with the database.

SQLAlchemy ORM (The "Object-Relational Mapper")

This is built on top of the Core. It allows you to define your database tables as Python classes.

  • declarative_base(): A factory function that creates a base class for your mapped classes.
  • mapped_column(): The ORM way of defining a column, linking it to a Python attribute.
  • relationship(): Defines a relationship between two tables (e.g., one-to-many, many-to-one).
  • sessionmaker: A factory for creating Session objects, which manage all conversations with the database.

A Practical Guide: From Setup to a Full Example

Let's build a simple application to manage users and their posts. We'll use the ORM approach as it's the most common use case.

Step 1: Installation

First, install SQLAlchemy. We'll also install psycopg2-binary for connecting to PostgreSQL and alembic for database migrations (a highly recommended practice).

Python SQLAlchemy怎么用?-图3
(图片来源网络,侵删)
pip install SQLAlchemy
pip install psycopg2-binary
pip install alembic

Step 2: Define the Models (Python Classes)

We define our database tables as Python classes. We'll create a User and a Post.

# models.py
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker, declarative_base
# 1. Create a base class for our mapped classes
Base = declarative_base()
class User(Base):
    __tablename__ = 'users'  # The name of the table in the database
    id = Column(Integer, primary_key=True)
    name = Column(String)
    email = Column(String, unique=True)
    # This defines a one-to-many relationship
    # A user can have many posts. 'Post.user' is the attribute on the Post class.
    posts = relationship("Post", back_populates="author")
    def __repr__(self):
        return f"<User(name='{self.name}', email='{self.email}')>"
class Post(Base):
    __tablename__ = 'posts'
    id = Column(Integer, primary_key=True)= Column(String)
    content = Column(String)
    user_id = Column(Integer, ForeignKey('users.id'))
    # This defines the many-to-one relationship
    # A post belongs to one user. 'author' is the attribute on the Post class.
    author = relationship("User", back_populates="posts")
    def __repr__(self):
        return f"<Post(title='{self.title}')>"
# 2. Create the database engine
# The engine is the core interface to the database.
# 'sqlite:///test.db' will create a file named 'test.db' in the current directory.
# For PostgreSQL, it would look like: 'postgresql://user:password@host:port/dbname'
engine = create_engine('sqlite:///test.db')
# 3. Create the tables in the database
# This will create the 'users' and 'posts' tables if they don't exist.
Base.metadata.create_all(engine)
# 4. Create a Session class to manage conversations with the DB
Session = sessionmaker(bind=engine)

Step 3: Interact with the Database (CRUD Operations)

Now we'll use our models to create, read, update, and delete data.

# main.py
from models import User, Post, engine, Session
# Create a new session
session = Session()
# --- CREATE ---
print("--- Creating Users and Posts ---")
# Create a new user
new_user = User(name="Alice", email="alice@example.com")
session.add(new_user)
# Create another user
another_user = User(name="Bob", email="bob@example.com")
session.add(another_user)
# Commit the new users to the database
session.commit()
# Create a post for Alice
post1 = Post(title="My First Post", content="Hello, world!", author=new_user)
session.add(post1)
# Create another post for Alice
post2 = Post(title="SQLAlchemy is fun!", content="I'm learning ORM.", author=new_user)
# Create a post for Bob
post3 = Post(title="Learning Python", content="It's a great language.", author=another_user)
session.add_all([post2, post3])
session.commit()
print("Users and Posts created successfully!")
# --- READ ---
print("\n--- Reading Data ---")
# Query all users
all_users = session.query(User).all()
print(f"All Users: {all_users}")
# Query a specific user by email
alice = session.query(User).filter_by(email="alice@example.com").first()
print(f"Found Alice: {alice}")
# Query all posts by Alice
alice_posts = session.query(Post).filter_by(user_id=alice.id).all()
print(f"Alice's Posts: {alice_posts}")
# Query posts with a specific title
sqlalchemy_post = session.query(Post).filter(Post.title == "SQLAlchemy is fun!").first()
print(f"Post found: {sqlalchemy_post}")
# --- UPDATE ---
print("\n--- Updating Data ---")
# Update Alice's email
alice.email = "alice.smith@example.com"
session.commit()
print(f"Alice's updated email: {alice.email}")
# --- DELETE ---
print("\n--- Deleting Data ---")
# Delete Bob's post about Python
post_to_delete = session.query(Post).filter_by(title="Learning Python").first()
if post_to_delete:
    session.delete(post_to_delete)
    session.commit()
    print("Deleted Bob's post.")
# Verify Bob's posts are gone
bob = session.query(User).filter_by(name="Bob").first()
print(f"Bob's remaining posts: {bob.posts}")
# Close the session
session.close()

When you run python main.py, you'll see the output and a test.db file will be created in your project directory.


Advanced Topics

Database Migrations with Alembic

Manually creating tables (Base.metadata.create_all) is fine for small projects, but for real applications, you need a way to track and apply changes to your database schema over time. This is where Alembic comes in.

  1. Initialize Alembic:

    alembic init alembic

    This creates an alembic directory with configuration files.

  2. Configure Alembic: Edit alembic.ini to point to your database URL. Edit alembic/env.py to import your Base and engine.

  3. Create a Migration Script: When you add a new column or table to your models.py, you tell Alembic to detect the change:

    alembic revision --autogenerate -m "Add a bio column to User"

    This creates a new migration script in alembic/versions/.

  4. Apply the Migration:

    alembic upgrade head

    This command applies all pending migrations to your database.

Querying Techniques

  • Filtering: session.query(User).filter(User.age > 30)
  • Ordering: session.query(User).order_by(User.name.desc())
  • Limiting: session.query(User).limit(10)
  • Joins: session.query(User, Post).join(Post).filter(User.name == "Alice")
  • Aggregations: session.query(User.name, func.count(Post.id)).join(Post).group_by(User.name)

One-to-Many and Many-to-Many Relationships

We saw a one-to-many relationship (User -> Post). SQLAlchemy also makes many-to-many relationships easy using an association table.

# In your models.py
from sqlalchemy import Table, Text
# Association table for the many-to-many relationship
post_tags = Table(
    'post_tags',
    Base.metadata,
    Column('post_id', Integer, ForeignKey('posts.id')),
    Column('tag_id', Integer, ForeignKey('tags.id'))
)
class Tag(Base):
    __tablename__ = 'tags'
    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)
    posts = relationship("Post", secondary=post_tags, back_populates="tags")
class Post(Base):
    # ... other columns ...
    tags = relationship("Tag", secondary=post_tags, back_populates="posts")

Summary

Feature Description
Core Low-level toolkit for SQL. Deals with tables, columns, and expressions.
ORM High-level layer. Maps Python classes to database tables.
Engine The interface to the database, managing connections.
Session A "workspace" for ORM operations, handling object states (transient, pending, persistent, detached).
Relationships relationship() and ForeignKey define how tables connect (one-to-many, many-to-many).
Migrations Alembic is the standard tool for managing database schema changes over time.

SQLAlchemy is a massive library, but this guide covers the fundamental concepts you need to get started. Its power lies in its flexibility, allowing you to use as much or as little of it as you need.

分享:
扫描分享到社交APP
上一篇
下一篇