在SQLAlchemy中,如果你想查询不重复的数据,可以使用distinct()方法。以下是一个简单的示例:
首先,导入必要的库和对象:
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
然后,定义一个简单的模型类:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
age = Column(Integer)
接下来,创建数据库连接和会话:
engine = create_engine('sqlite:///example.db')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
现在,假设你想要查询User表中不重复的name字段,你可以使用以下代码:
from sqlalchemy import distinct
unique_names = session.query(distinct(User.name)).all()
for name in unique_names:
print(name)
这将会输出User表中所有不重复的name值。请注意,如果你想要查询多个字段的不重复组合,你可以在distinct()方法中传递多个参数。例如,要查询不重复的name和age组合,可以这样做:
unique_name_age_combinations = session.query(distinct(User.name, User.age)).all()
for name, age in unique_name_age_combinations:
print(name, age)
这将输出User表中不重复的name和age组合。
在上述示例的基础上,我将展示如何向数据库中插入一些数据以便进行查询操作,并演示如何使用filter和order_by进行筛选和排序。
首先,我们向数据库中插入一些用户数据:
# 添加用户数据
users = [
User(name="Alice", age=30),
User(name="Bob", age=25),
User(name="Alice", age=35),
User(name="Charlie", age=22),
User(name="Bob", age=28),
User(name="Alice", age=30)
]
# 将用户添加到数据库会话
for user in users:
session.add(user)
# 提交更改以保存到数据库
session.commit()
现在我们有了一些数据,接下来演示如何使用filter过滤查询结果,假设我们只想要年龄大于等于28的不重复的name和age组合:
unique_name_age_combinations = (
session.query(distinct(User.name, User.age))
.filter(User.age >= 28)
.all()
)
for name, age in unique_name_age_combinations:
print(name, age)
接下来,我们将查询结果按照年龄进行排序。为此,我们可以使用order_by()方法:
unique_name_age_combinations = (
session.query(distinct(User.name, User.age))
.filter(User.age >= 28)
.order_by(User.age)
.all()
)
for name, age in unique_name_age_combinations:
print(name, age)
在这个例子中,查询的结果将按照年龄升序排列。如果需要降序排列,可以使用desc()方法:
from sqlalchemy import desc
unique_name_age_combinations = (
session.query(distinct(User.name, User.age))
.filter(User.age >= 28)
.order_by(desc(User.age))
.all()
)
for name, age in unique_name_age_combinations:
print(name, age)
这样,查询结果将按照年龄降序排列。
在这个示例中,我将向您展示如何使用分组、计数和分页来执行更复杂的查询。
首先,让我们看一下如何使用group_by()方法对查询结果进行分组。假设我们想要统计每个名字的用户数量:
from sqlalchemy import func
name_counts = (
session.query(User.name, func.count(User.name))
.group_by(User.name)
.all()
)
for name, count in name_counts:
print(f"{
name}: {
count}")
在这个查询中,我们使用了SQLAlchemy的func模块中的count()函数来统计每个名字的用户数量。
接下来,让我们看一下如何使用limit()和offset()方法进行分页。假设我们想要查询年龄大于等于25的用户,并按年龄升序排列,每页显示2个用户:
page_size = 2
page_number = 1
users_over_25 = (
session.query(User.name, User.age)
.filter(User.age >= 25)
.order_by(User.age)
.limit(page_size)
.offset((page_number - 1) * page_size)
.all()
)
for user in users_over_25:
print(user)
在这个示例中,我们使用limit()方法限制每页显示的用户数量,使用offset()方法设置查询的起始位置。您可以更改page_number变量以获取不同页码的用户。
最后,让我们看一下如何执行多表查询。首先,我们需要创建一个新的模型类来表示用户的地址:
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'))
city = Column(String)
street = Column(String)
user = relationship("User", back_populates="addresses")
User.addresses = relationship("Address", back_populates="user")
接下来,更新数据库结构并插入一些地址数据:
Base.metadata.create_all(engine)
addresses = [
Address(user_id=1, city="New York", street="Main St"),
Address(user_id=2, city="San Francisco", street="Market St"),
Address(user_id=3, city="Los Angeles", street="Sunset Blvd")
]
for address in addresses:
session.add(address)
session.commit()
现在,我们可以执行一个连接查询来获取用户及其地址:
from sqlalchemy.orm import joinedload
users_with_addresses = (
session.query(User)
.options(joinedload(User.addresses))
.all()
)
for user in users_with_addresses:
print(f"{
user.name}, {
user.age}")
for address in user.addresses:
print(f" {
address.city}, {
address.street}")
在这个查询中,我们使用joinedload()方法来预加载与用户相关的地址,这样我们就可以在一个查询中获取所有相关的数据。