灵活使用 SQLAlchemy 中的 ORM 查询

本文介绍了 SQLAlchemy ORM 的常见查询方式,包括根据主键获取记录、AND 和 OR 查询、使用列表或字典解包传参、内连接和外连接等,并提供了实践示例,旨在提高查询效率和可读性。
摘要由CSDN通过智能技术生成

之前做查询一直觉得直接拼 SQL 比较方便,用了 SQLAlchemy 的 ORM 查询之后,发现也还可以,还提高了可读性。

这篇文章主要说说 SQLAlchemy 常用的 ORM 查询方式,偏实践。看了之后,对付开发中的查询需求,我觉得可以满足不少。

为方便说明,假设有如下数据

图书表 books

+----+--------+--------------------------+-------+
| id | cat_id | name                     | price |
+----+--------+--------------------------+-------+
|  1 |      1 | 生死疲劳                 | 40.40 |
|  2 |      1 | 皮囊                     | 31.80 |
|  3 |      2 | 半小时漫画中国史         | 33.60 |
|  4 |      2 | 耶路撒冷三千年           | 55.60 |
|  5 |      2 | 国家宝藏                 | 52.80 |
|  6 |      3 | 时间简史                 | 31.10 |
|  7 |      3 | 宇宙简史                 | 22.10 |
|  8 |      3 | 自然史                   | 26.10 |
|  9 |      3 | 人类简史                 | 40.80 |
| 10 |      3 | 万物简史                 | 33.20 |
+----+--------+--------------------------+-------+

分类表 categories

+----+--------------+
| id | name         |
+----+--------------+
|  1 | 文学         |
|  2 | 人文社科     |
|  3 | 科技         |
+----+--------------+

ORM 对象定义如下


注意:本文 Python 代码在以下环境测试通过

  • Python 3.6.0
  • PyMySQL 0.8.1
  • SQLAlchemy 1.2.8

# coding=utf-8

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Numeric
from sqlalchemy.orm import sessionmaker

Base = declarative_base()
engine = create_engine('mysql+pymysql://username:password'
                       '@127.0.0.1:3306/db_name?charset=utf8')
Session = sessionmaker(bind=engine)

session = Session()


def to_dict(self):
    return {c.name: getattr(self, c.name, None)
            for c in self.__table__.columns}
Base.to_dict = to_dict


class Book(Base):
    __tablename__ = 'books'

    id = Column(Integer, primary_key=True)
    cat_id = Column(Integer)
    name = Column('name', String(120))
    price = Column('price', Numeric)


class Category(Base):
    __tablename__ = 'categories'

    id = Column(Integer, primary_key=True)
    name = Column('name', String(30))

好了,下面进入正题。

1 根据主键获取记录

当我们获取图书的详情时,很容易用到。

book_id = 1
book = session.query(Book).get(book_id)
print(book and book.to_dict())

直接 get(primary_key) 就得到结果

{'id': 1, 'cat_id': 1, 'name': '生死疲劳',
 'price': Decimal('40.40')}

当然,这样也可以

book_id = 1
book = session.query(Book) \
    .filter(Book.id == book_id) \
    .first()
print(book and book.to_dict())

不过,还是前一种方式简洁一些。

2 AND 查询

我们最常用到的就是这种查询,比如我要获取 cat_id 为 1 且价格大于 35 的书

books = session.query(Book) \
    .filter(Book.cat_id == 1,
            Book.price > 35) \
    .all()
print([v.to_dict() for v in books])

执行后,得到结果

[{'id': 1, 'cat_id': 1, 'n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值