SQLAlchemy查询不重复的数据

在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()方法来预加载与用户相关的地址,这样我们就可以在一个查询中获取所有相关的数据。

猜你喜欢

转载自blog.csdn.net/lilongsy/article/details/129725047
今日推荐