python SQLAlcheme ORM 对象关系映射

最近在使用Fastapi编写web接口,涉及mysql数据库了记录一下使用SQLAlcheme:  https://www.osgeo.cn/sqlalchemy/orm/tutorial.htmlfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL: str = 'mysql+pymysql://root:123456@127.0.0.1:3306/user?charset=utf8'

# 1.生成一个SQLAlchemy引擎  初始化数据库连接:
engine = create_engine(
    SQLALCHEMY_DATABASE_URL, pool_pre_ping=True, echo=True
)
# 2.基于数据库引擎生成sessionlocal类,这个类的每一个实例都是一个数据库的会话 注意命名为SessionLocal,与sqlalchemy的session分隔开 SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) # DBSession类型 session = SessionLocal()
# 3.创建一个基类,用来创建数据库中表时使用
Base = declarative_base() # 该基类维护一个与该基相关的类和表的目录-这称为 声明性基类 . 既然我们有了一个“基”,就可以根据它定义任意数量的映射类就可以创建表了
# 4.根据第二步创建的SessionLocal()创建临时会话:我们现在准备开始与数据库对话。ORM对数据库的“句柄”是 Session . 当我们第一次设置应用程序时,与我们的 create_engine() 语句,我们定义 Session 将用作新工厂的类 Session 物体:  就是本文中SessionLocal
session = SessionLocal()
# 5,数据库添加数据
ed_user = User(name='ed',email='tarzan@qq.com',hashed_password='tyuiytouyih@')
# 6.使用数据库会话进行add
session.add(ed_user) # 尚未发出SQL,对象尚未由数据库中的一行表示
ed_user.name = 'tarzan' # 修改

  #我们可以增加更多 User 对象同时使用 add_all() : 

  session.add_all([

User(name='ed',email='tarzan@qq.com',hashed_password='tyuiytouyih@'),
User(name='ed',email='tarzan@qq.com',hashed_password='tyuiytouyih@')])
# 查看当前事务
session.query(User).filter_by(name='ed').first()
# 7.我们告诉 Session 我们希望发布对数据库的所有剩余更改,并提交整个过程中一直在进行的事务。我们这样做通过 Session.commit() . 这个 Session 发出 UPDATE “ed”上昵称更改的声明,以及 INSERT 两个新的声明 User 我们添加的对象:
session.commit()
# 8.回滚
session.rollback()
# 9.查询
for instance in session.query(User).order_by(User.id):
  print(instance.name)
for u in session.query(User).order_by(User.id)[1:3]
  print(u)
#过滤结果 filter_by() ,使用关键字参数
for name, in session.query(User.name).filter_by(fullname='Ed Jones'):
# 或… filter() ,它使用更灵活的SQL表达式语言构造。这些允许您在映射类上使用具有类级属性的常规python运算符:
for name, in session.query(User.name).filter(User.fullname=='Ed Jones'):
# 这个 Query 对象完全 生成的 ,这意味着大多数方法调用都返回一个新的 Query 对象,在此对象上可以添加其他条件,可以调用 filter() 两次
for user in session.query(User).filter(User.name=='ed').filter(User.fullname=='Ed Jones'):
  print(user)

常用筛选器运算符

下面是在 filter() :

  • query.filter(User.name == 'ed')
  • query.filter(User.name != 'ed')
  • query.filter(User.name.like('%ed%'))  # 区分大小写
    query.filter(User.name.ilike('%ed%'))  # 不区分大小写
  • query.filter(User.name.in_(['ed', 'wendy', 'jack']))
    
    # works with query objects too:
    query.filter(User.name.in_(session.query(User.name).filter(User.name.like('%ed%'))))
    
    # use tuple_() for composite (multi-column) queries
    from sqlalchemy import tuple_
    query.filter(
        tuple_(User.name, User.nickname).\
        in_([('ed', 'edsnickname'), ('wendy', 'windy')])
    )
  • ColumnOperators.not_in() ::

    query.filter(~User.name.in_(['ed', 'wendy', 'jack']))
  • ColumnOperators.is_() ::

    query.filter(User.name == None)
    
    # alternatively, if pep8/linters are a concern
    query.filter(User.name.is_(None))
  • ColumnOperators.is_not() ::

    query.filter(User.name != None)
    
    # alternatively, if pep8/linters are a concern
    query.filter(User.name.is_not(None))
  • AND ::

    # use and_()
    from sqlalchemy import and_
    query.filter(and_(User.name == 'ed', User.fullname == 'Ed Jones'))
    
    # or send multiple expressions to .filter()
    query.filter(User.name == 'ed', User.fullname == 'Ed Jones')
    
    # or chain multiple filter()/filter_by() calls
    query.filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')

注解

确保使用 and_() 和 not Python and 接线员!

  • OR ::

    from sqlalchemy import or_
    query.filter(or_(User.name == 'ed', User.name == 'wendy'))

注解

确保使用 or_() 和 not Python or 接线员!

注解

ColumnOperators.match() 使用特定于数据库的 MATCH 或 CONTAINS 函数;其行为因后端而异,在某些后端(如sqlite)上不可用。

 
 
 
 


 

 

posted @ 2022-01-20 11:50  Tarzen  阅读(213)  评论(0编辑  收藏  举报