Using SQLAlchemy
Python ORM in practice: Use SQLAlchemy to operate the database elegantly
In application development, almost every project cannot bypass the database. Although it is straightforward to directly use SQL statements to operate the database, when the project scale becomes larger and the table structure becomes more complex, it will become more and more difficult to maintain these scattered SQL codes. The emergence of ORM (Object Relational Mapping) is to solve this problem. It allows us to operate the database in a familiar object-oriented way, and SQLAlchemy is one of the most mature and powerful ORM frameworks in the Python ecosystem. This article will take you from installation and configuration to advanced-features, and master the core usage of SQLAlchemy step by step.
1. What is ORM? Why is it needed?
The core idea of ORM is: database table ↔ Python class, a row of records in the table ↔ an instance of the class, columns in the table ↔ attributes of the class.
Traditional method vs ORM method
When not using ORM, the results we query from the database are usually a list of tuples:
This method requires us to manually handle the order and type of fields, which is especially error-prone when involving multi-table related queries. Through ORM, we can process data in the form of objects:
In this way, when we access the data, we can useuser.nameinstead ofuser[1], the readability and maintainability of the code have been greatly improved.
2. Installation and basic configuration
2.1 Install SQLAlchemy
The core package of SQLAlchemy can be installed directly through pip:
If you use MySQL database, you also need to install the corresponding database driver, for examplepymysqlormysql-connector-python:
2.2 Create database connection and session
The following is a standard basic configuration, including the definition of the connection engine, session factory and base class:
hereSessionLocalIt is the factory for our subsequent CRUD operations. Each request or operation should create an independent session.
3. Define database model (table structure)
In SQLAlchemy, a model class corresponds to a table in the database. Let's first look at a simple user model:
3.1 Single table model
Some common parameters in model definition:
primary_key=True: Primary key.index=True: Create an index for this column to improve query efficiency.unique=True: Ensure that the column value is unique.nullable=False: Equivalent to databaseNOT NULLconstraint.
3.2 Define one-to-many and many-to-one relationships
Tables in reality often have related relationships, such as one user can publish multiple articles (one-to-many). In SQLAlchemy we can passForeignKeyandrelationshipTo establish this relationship:
ForeignKey('users.id')Specifies the foreign key constraint, corresponding touserstableidfield.relationshipIt is a relationship declaration at the ORM level, allowing us to directly passuser.postsGet all articles of this user, or bypost.authorGet the author of the article.
4. Basic database operations (CRUD)
After defining the model, we usually perform a table creation operation when the application starts:
Next, let's see how to perform add, delete, modify and check operations. In order to keep the code clear, each operation is encapsulated into a function and passedtry...finallyMake sure the session is closed properly.
4.1 Create records
4.2 Query records
SQLAlchemy provides a very flexible way to build queries:
Common query methods:
all(): Returns a list of all results.first(): Return the first result, if not, returnNone。filter(): Add filter conditions, multiple calls can be made in a chain.filter_by(): Easier, use keyword arguments for filtering (e.g.filter_by(email=email))。
4.3 Update records
Updates generally require first finding the record to be modified, then modifying the attributes, and then submitting the transaction:
4.4 Delete records
The deletion operation is similar, query first and then calldelete()method:
5. Manipulate associated objects
One of the advantages of ORM is that it can naturally handle the relationships between objects. Suppose we want to create a user and add several articles to it at the same time. We can do this:
When querying a user, if we want all his articles to be loaded together (to avoid the N+1 query problem), we can usejoinedloadTo preload:
6. advanced-features
6.1 Transaction Management
For update operations involving multiple records, transactions can guarantee data consistency. SQLAlchemy enables transactions by default, we need to manually commit or rollback:
6.2 Asynchronous support (for SQLAlchemy 2.0+)
In high-concurrency scenarios, asynchronous operations can significantly improve performance. SQLAlchemy 2.0 provides complete asynchronous support:
When using asynchronous, pay attention to the matchingasyncmyoraiomysqlWait for asynchronous driver.
7. Some practical suggestions
- Manage session life cycle: It is recommended to use a context manager to encapsulate the session, or use dependency injection (such as FastAPI's
Depends) automatically handles the creation and closing of sessions. - Avoid long transactions: Keep transactions as short as possible to reduce the time of locking resources, especially in high concurrent write scenarios.
- Batch Operation: Used when a large amount of data needs to be inserted or updated
session.bulk_insert_mappings()orsession.bulk_save_objects()can get better performance. - Reasonable selection of loading strategies: For associated attributes, choose according to business scenarios
joinedload(preloaded),selectinload(Secondary query preloading) or keep the default lazy loading. - Make good use of type hints: With modern IDEs, type hints allow you to get better auto-completion and error checking when writing queries.
8. Summary
As the most mature ORM framework in Python, SQLAlchemy not only retains the expressive power of original SQL, but also provides an object-oriented operation interface. It can handle everything from simple single-table CRUD to complex relationship processing, transaction control, and asynchronous operations. Through the introduction of this article, I believe you have mastered the core usage of SQLAlchemy. Next, try replacing original SQL operations with SQLAlchemy in your project to experience the improvement in development efficiency it brings.
If you want to learn more, I recommend reading SQLAlchemy 官方文档, which contains a lot of advanced usage and best practices.

