Python > Working with Data > Databases > Object-Relational Mappers (ORMs) - Introduction to SQLAlchemy
SQLAlchemy: Defining a Simple Model and Creating a Table
This snippet demonstrates how to define a simple database model using SQLAlchemy and create the corresponding table in a database. It provides a basic foundation for interacting with databases using an ORM.
Installation
Before using SQLAlchemy, you need to install it using pip. This command will install the core SQLAlchemy library.
pip install sqlalchemy
Import Necessary Modules
This section imports the required modules from SQLAlchemy. create_engine
is used to connect to the database. Column
, Integer
, and String
define the data types for table columns. declarative_base
is used to create a base class for declarative models, and sessionmaker
is used to create database sessions.
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Define the Database Engine
This line creates the database engine, which is the entry point for interacting with the database. Here, we're using a SQLite database named 'my_database.db'. The echo=True
argument enables logging of SQL statements, which is helpful for debugging.
engine = create_engine('sqlite:///./my_database.db', echo=True)
Define the Base
declarative_base()
creates a base class that all declarative models should inherit from. This base class automatically handles table metadata and allows you to define tables in an object-oriented way.
Base = declarative_base()
Define the Model (Table)
This section defines the User
model, which represents the 'users' table in the database. __tablename__
specifies the table name. Each Column
defines a column in the table, with its data type and constraints (e.g., primary_key=True
). The __repr__
method defines a string representation of the object, which is useful for debugging.
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
def __repr__(self):
return f'<User(name=\'{self.name}\', age={self.age})>'
Create the Table
This line creates all tables defined by the models that inherit from the Base
. It uses the engine to connect to the database and execute the necessary SQL statements to create the tables.
Base.metadata.create_all(engine)
Create a Session
A session is the central object for interacting with the database. It manages database transactions and allows you to query and persist data. We create a session factory (sessionmaker
) bound to the engine, and then create a new session instance.
Session = sessionmaker(bind=engine)
session = Session()
Adding Data to the Table
Here, we create a new User
object, add it to the session, and then commit the changes to the database. session.add()
stages the object for insertion, and session.commit()
persists the changes to the database.
new_user = User(name='Alice', age=30)
session.add(new_user)
session.commit()
Querying Data
This code queries all users from the database using session.query(User).all()
. It then iterates through the results and prints each user's information, leveraging the __repr__
method we defined earlier.
users = session.query(User).all()
for user in users:
print(user)
Complete Example
This is the complete example incorporating all the previous parts. It shows how to define a model, create a table, add data, and query the database.
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('sqlite:///./my_database.db', echo=True)
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
def __repr__(self):
return f'<User(name=\'{self.name}\', age={self.age})>'
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
new_user = User(name='Alice', age=30)
session.add(new_user)
session.commit()
users = session.query(User).all()
for user in users:
print(user)
Concepts Behind the Snippet
This snippet introduces the core concepts of ORMs: defining database tables as Python classes (models), mapping data types between Python and the database, and using a session to manage database transactions. SQLAlchemy abstracts away the need to write raw SQL queries, allowing you to interact with the database using Python objects.
Real-Life Use Case
Imagine you are building a web application that needs to store user data. Using SQLAlchemy, you can define a User
model with attributes like name, email, and password. SQLAlchemy allows you to easily store, retrieve, and update user data in the database without writing complex SQL queries manually. This simplifies development and improves code maintainability.
Best Practices
Interview Tip
Be prepared to explain the benefits of using an ORM over raw SQL queries, such as increased productivity, improved code readability, and reduced risk of SQL injection vulnerabilities. Also, be able to discuss the trade-offs, such as potential performance overhead and the learning curve associated with the ORM framework.
When to Use Them
Use ORMs when you want to simplify database interactions, improve code readability, and reduce the risk of SQL injection vulnerabilities. ORMs are particularly well-suited for applications with complex data models and frequent database operations. However, for simple applications with minimal database interaction, raw SQL queries might be sufficient and more performant.
Memory Footprint
SQLAlchemy's memory footprint depends on the size of the data being processed and the complexity of the queries. It's generally efficient, but it's important to be mindful of memory usage when dealing with large datasets. Use techniques like pagination and lazy loading to reduce memory consumption.
Alternatives
Alternatives to SQLAlchemy include: psycopg2
for PostgreSQL or sqlite3
for SQLite.
Pros
Cons
FAQ
-
What is an ORM?
An ORM (Object-Relational Mapper) is a programming technique that converts data between incompatible type systems using object-oriented programming languages. This creates, in effect, a 'virtual object database' that can be used from within the programming language. -
Why use SQLAlchemy?
SQLAlchemy simplifies database interactions, improves code readability, and reduces the risk of SQL injection vulnerabilities. It provides a high level of abstraction while still allowing fine-grained control over the underlying SQL. -
What databases does SQLAlchemy support?
SQLAlchemy supports a wide range of databases, including PostgreSQL, MySQL, SQLite, Oracle, and Microsoft SQL Server.