SQLAlchemy ORM 参考

ORM


Session

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine(‘sqlite:///:memory:‘, echo=False)
Session = sessionmaker(bind=engine)
session = Session()

echo 负责设定是否输出生成的 SQL 语句。

create_engine 返回的是一个 Engine 对象,它负责对接 DBAPI。Session 对象会更多被直接使用。

session 某种意义上类似于一个缓存,他有 commit, rollback, close 等方法。也因此 session 实例的生命周期维护应该位于使用它们的函数之外,与具体的应用逻辑区分开,以避免数据污染和保证 rollback/close 的调用。如:– 参考

from contextlib import contextmanager

@contextmanager
def session_scope():
    """Provide a transactional scope around a series of operations."""
    session = Session()
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()

def run_my_program():
    with session_scope() as session:
        ThingOne().go(session)
        ThingTwo().go(session)

映射对象的声明

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String

Base = declarative_base()

class User(Base):
    __tablename__ = ‘user‘

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

从 Python 类到 sql 表,需要一套映射逻辑,sqlalchemy 提供了一套默认的解决方案,就是 declarative_base

这里单独的一行 Base=declarative_base() 表示了你可以有很多种方式自定义基类,比如继承 Base,或者给 declarative_base(**kwargs) 传参。– 参考

至于 User 类,由于 sqlalchemy 默认不会去做任何推导,你需要显示指定 __tablename__ 参数和至少一个主键。

Integer 类型没有指定长度,是因为这种修饰参数仅在建表时有用。

Query


new

tim = User(name=‘tim‘)
session.add(tim)
session.flush()

sqlalchemy 对待请求的处理方式是惰性的,他只在必要的时候才访问数据库。必要的一种定义是 query:

session.query(User).filter_by(name=‘tim‘)

立即同步到数据库的方式是使用 .flush() 方法。

另外一个非常有趣的特性是,sqlalchemy 能够在同一个 session 中分别出表记录的唯一性。即:

>>> tim is session.query(User).filter_by(name=‘tim‘)
>>> True

对于同一条数据库记录,不管是你新建的,还是多次从库中取出的,他们的 Python id 都是一样的。这种区分就是前面提到的 映射声明必须提供主键 所带来的一个好处。

query 对象

query() 的参数可以很多变,可以是一个 Model 类,或他的某些属性的组合:

foo = session.query(User, User.id).filter(User.name==‘tim‘).first()

这种 query 方式返回的元组对象都是关键字命名的,而且支持属性式访问,如:

>>> foo.User.id == foo.id
>>> True

如果想起别名,可以使用 .label() 方法:

>>> foo = session.query(User.id.label(‘user_id‘)).filter_by(name=‘tim‘)
>>> foo.user_id
>>> 1

对于 LIMIT 和 OFFSET 参数,可以直接对 Query 对象使用 Python 切片操作。

session.query(User)[20:10]

最后,Query 对象是可迭代的。尽管上面的例子为了偷懒没有使用过迭代方法,但它是支持的!

filter

filter() 较于 filter_by() 是一种更通用的方法,支持所有的 sql 表达式。filter() 返回的仍然是一个 Query 对象,所以你可以连续调用 filter() 方法,或者图省事把复合查询语句放进同一个 filter() 里

session.query(User).filter(id>1, name==‘tim‘)

session.query(User).filter(id>1).filter(name==‘tim‘)

一些常用的表达式语句:

  • User.name == ‘tim‘
  • User.name != ‘tim‘
  • User.name.like(‘tim‘)
  • User.name.in_([‘tim‘, ‘White‘])
  • ~User.name.in_([‘tim‘, ‘white‘])
  • User.name == None or User.name.is_(None)
  • User.name != None or User.name.isnot(None)
  • from sqlalchemy import or_ /// filter(or_(expr1, expr2))
  • User.name.match(‘tim‘)

all(), one(), first()

Query 对象虽然是可迭代的,但对于多数确定需求的状况,我们可能更希望直接把需要的数据取出来。

all()first() 顾名思义,特别的是 one()

它较于 first() 多了一条约束,即Query 对象的结果集必须只包含一个对象,否则报错,即:

session.query(User).filter(name==‘tim‘).one()

等价于:

foo = session.quert(User).filter(name=‘tim‘)
assert len(foo.all()) == 1
return foo.first()

SQL

在如 filter()order_by() 这样的方法中,条件表达式还可以是原始的 sql 语句,只需要用 text() 把语句包起来:

from sqlalchemy import text

users = session.query(User).filter(text(‘id<10‘)).order_by(text(‘id‘))

另一种更彻底的 sql 执行方式是使用 from_statement() 方法:

session.query(User).from_statement(text(‘SELECT * FROM user where id<10 and status=1‘)).all()

此时还可以直接 Query 列名:

>>> session.query(‘id‘, ‘name‘, ‘status‘).from_statement(‘SELECT * from user where class=3‘).all()
>>> [(1, ‘jack‘, 0), (2, ‘rose‘, 1)]

counting

一种简单的计数是对 Query 对象使用 count() 方法,用于返回 Query 对象的行数。

另一种较复杂的是 func.count(),它支持细分计数:

from sqlalchemy import func

session.query(func.count(User.class), User.class).filter_by(User.class=‘a‘)

session.query(func.count(User.class), User.class).group_by(User.class).all()

关系

时间: 2024-08-30 04:09:10

SQLAlchemy ORM 参考的相关文章

SQLAlchemy使用笔记--SQLAlchemy ORM(二)

参考: http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#building-a-relationship http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#working-with-related-objects 建立表之间带关系 建立外建 在address添加user的外键 from sqlalchemy import ForeignKey, Column, String

基础入门_Python-模块和包.深入SQLAlchemy之SQLAlchemy ORM重构表?

简单介绍: 说明: 此模块主要用于将关系型数据库表映射到PY的类,行映射到PY类的实例,列映射为PY实例的属性,由于其兼容众多DB-API及扩展,SO可以优先考虑数据模型,而忽略底层的DB-API切换,数据迁移更方便. 快速安装: pip install --upgrade SQLAlchemy 定义结构: #!/usr/bin/env python # -*- coding: utf-8 -*- """ # # Authors: limanman # OsChina: ht

SqlAlchemy ORM

SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果 Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如: MySQL-Python mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname&g

python 学习笔记十一 SQLALchemy ORM(进阶篇)

SqlAlchemy ORM SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果. Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如: MySQL-Python mysql+mysqldb://<user>:<password>@<host>[:<port&g

day11:SqlAlchemy ORM

一.外键关联,relationship() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79

python之SQLAlchemy ORM 上

前言: SQLAlchmey是暑假学的,当时学完后也没及时写博客整理下.这篇博客主要介绍下SQLAlchemy及基本操作,写完后有空做个堡垒机小项目.下篇博客整理写篇关于Web框架和django基础~~ 一.ORM介绍 orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了保证一致的使用习惯,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们

sqlalchemy orm 层面删除数据注意

#encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_,Text, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker,relationship,backref from random import r

sqlalchemy orm的cascade的参数

#encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_,Text, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker,relationship,backref from random import r

在SQLAlchemy ORM中动态变更表名

在开发过程中,经常会遇到几张表结构相同,仅仅表名不一样.这在直接使用SQL语句进行查询的环境中处理起来很简单,但如果使用了SQLAlchemy ORM之后,因在model定义时就确定了表名,就需要用其他方法进行表名的变更. 假定数据库中有两张表:user,user_1,下面用一个简单程序展示如何在查询时变更表名. 使用declarative_base定义的model from sqlalchemy import create_engine from sqlalchemy import Table