乐趣区

关于python:SQLAlchemy使用

简介

SQLAlchemy 是 Python 语言的一款风行的 ORM(Object Relational Mapper)框架,该框架建设在数据库 API 之上,应用关系对象映射进行数据库操作,行将对象转换成 SQL,而后应用数据 API 执行 SQL 并获取执行后果。

装置 SQLAlchemy 也很简略,间接应用 pip 装置即可。

pip install sqlalchemy

上面重点介绍 SQLAlchemy 的应用。

版本查看

import sqlalchemy
sqlalchemy.__version__    # 1.1.9

以后 sqlalchemy 版本为 1.1.9

连贯数据库

from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True)
  • engine 是 Engine 类的一个对象
  • echo=True 表明开启 logging 模块的日志
  • 数据库连贯:engine://user:password@host:port/database,其中 engine 为 mysql+pymysql,或者是 mysql+mysqldb,或者是 oracle+cx_oracle 等等

<!–more–>

创立表

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


engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True)
Base = declarative_base()  # 生成 Model 类的基类

class User1(Base):
    __tablename__ = 'user1'
    
    extend_existing = True
    # 定义三个列
    id = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)
    age  = Column(Integer)
    
        
    def __repr__(self):
        return 'User(id={}, name={}, age={})'.format(self.id, self,name, self.age)
    
    def __str__(self):
        return self.__repr__()
        
Base.metadata.create_all(engine)  # 创立所有表
Base.metadata.drop_all(engine)  # 删除所有表

# 定义类的实例办法 1
u1 = User()    # User 类只接管一个地位参数 self,和关键字参数 **kwargs
u1.name = 'aa'  # 给 User 类的各个列赋值
u1.age=19
print(u1)  # User(id=None, name=aa, age=19)

# 定义类的实例办法 2
u2 = User(name='bb', age='123')
print(u2)  # User(id=None, name=bb, age=123)
  • 派生类 User 会继承基类 Base 的初始化函数 __init__,会主动的承受咱们所定义的列对应的关键字参数
  • 未赋值的列会用 None 初始化,如下面的 id

Session

SQLAlchemy 真正解决数据库的局部是 Session。

如果曾经创立好了一个 Engine 对象 engine,那么能够用以下语句创立一个 Session

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)

如果 engine 为创立好,则能够用以下语句创立

Session = sessionmaker()

当 engine 创立好之后,在配置 Session 即可

Session.configure(bind=engine)

当须要和数据库交互的时候,就须要实例化 Session

session = Session()

创立实现之后这个 session 并没有马上获取数据库连贯。只有当这个 session 第一次操作数据库的时候才会从 Engine 保护的连接池中获取一个连贯,并持有这个连贯始终到咱们提交了所有的扭转或者敞开了这个 session。

DML

insert

user = User(name='haha', age='123')
session.add(user)
session.commit()

如果这个 commit 的过程中产生异样,则后续所有的 commit 都无奈执行,因而 DML 都须要放在 try…except 中解决,如下

user = User(name='flowsnow', age=18)
session.add(user)
try:
    session.commit()
except Exception as e:
    session.rollback()
    raise e

update

和 insert 相似,都是应用 session.add 办法,然而 update 操作的时候须要数据库中存在带操作的记录。

user.age = 20
session.add(user)
try:
    session.commit()
except Exception as e:
    session.rollback()
    raise e

delete

删除之前必须确保数据库中存在要删除的记录。

session.delete(user)    # user 必须曾经存在
try:
    session.commit()
except Exception as e:
    session.rollback()
    raise e

QUERY

for u in session.query(User).filter(User.age < 20).order_by(User.age.desc())[1:3]:
    print(u)

此条语句经 ORM 转换之后的 SQL 如下:

SELECT
    USER.id AS user_id,
    USER.NAME AS user_name,
    USER.age AS user_age
FROM USER
WHERE USER.age < % (age_1) s
ORDER BY USER.age DESC
LIMIT % (param_1) s, % (param_2) s

query 函数的返回后果为一个 Query 对象,Query 对象是可迭代的,反对切片操作。

上面列举常见的 filter 操作

  • 相等

    query.filter(User.name == 'suncle')
  • 不相等

    query.filter(User.name != 'suncle')
  • 含糊匹配 like:大小写敏感

    query.filter(User.name.like('%sun%'))
  • 含糊匹配 ilike:大小写不敏感

    query.filter(User.name.ilike('%sun%'))
  • IN

    query.filter(User.name.in_(['suncle', 'abc', 'suncle']))
    
    # 也反对 Query 对象
    query.filter(User.name.in_(session.query(User.name).filter(User.name.like('%sun%'))
    ))
  • NOT IN

    query.filter(~User.name.in_(['ed', 'wendy', 'jack']))
  • IS NULL

    query.filter(User.name == None)
    
    # 下面的写法不合乎 pep8 标准,IDE 会给出提醒,能够用上面的办法代替,pep8 的写法是 is None
    query.filter(User.name.is_(None))
  • IS NOT NULL

    query.filter(User.name != None)
    
    # 下面的写法不合乎 pep8 标准,IDE 会给出提醒,能够用上面的办法代替,pep8 的写法是 is not None
    query.filter(User.name.isnot(None))
  • AND

    # 办法 1:应用 and_() 办法
    from sqlalchemy import and_
    query.filter(and_(User.name == 'flowsnow', User.age == 18))
    
    # 办法 2:filter() 反对多个关键字参数
    query.filter(User.name == 'flowsnow', User.age == 18)
    
    # 办法 3:屡次调用 filter 函数
    query.filter(User.name == 'flowsnow').filter(User.age == 18)
  • OR

    from sqlalchemy import or_
    query.filter(or_(User.name == 'suncle', User.name == 'flowsnow'))

上面列举 SQL 反对的常见的 function

from sqlalchemy import func
session.query(func.count(User.id)).first() # count
session.query(func.max(User.age)).first() # max
session.query(func.avg(User.age)).first() # avg

Relationship

表和表之间会有外键关系,数据库的外键关系在 ORM 中的应用办法如下:

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

Base = declarative_base()  # 生成 Model 类的基类

class Author(Base):  # 作者类
    __tablename__ = 'author'
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(64), unique=True, nullable=False)
    
    posts = relationship('Post')
    
    def __repr__(self):
        return 'Author<id={},name={}>'.format(self.id, self.name)
    
    def __str__(self):
        return self.__repr__()
    
    
class Post(Base):  # 文章类
    __tablename__ = 'post'
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(128), nullable=False, index=True)
    content = Column(String(8096), nullable=False)
    author_id = Column(Integer, ForeignKey('author.id'), nullable=False)
    
    author = relationship('Author')
    
    def __repr__(self):
        return 'Post<id={}, title={}>'.format(self.id, self.title)
    
    def __str__(self):
        return self.__repr__()
    

engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

# 新增一个作者
author = Author()
author.name = 'flowsnow'
session.add(author)
session.commit()
print(author)  # Author<id=1,name=flowsnow>

# 新增一篇文章
post = Post()
post.title = 'first post'
post.content = 'oihdoshfohro'
post.author = author
session.add(post)
session.commit()
print(author.posts)  # [Post<id=1, title=first post>]

# 再新增一篇文章
post = Post()
post.title = 'second post'
post.content = 'liabhgekegpaerg'
post.author = author
session.add(post)
session.commit()
print(author.posts)  # [Post<id=1, title=first post>, Post<id=2, title=second post>]

数据库保护数据之间的外键关系会耗费数据库资源,影响性能,在大型的利用中个别不应用外键等数据库高级个性,而是由利用框架来保护数据之间的束缚。


参考

  1. 官网文档 -Object Relational Tutorial
  2. A step-by-step SQLAlchemy tutorial
  3. 廖雪峰 - 应用 SQLAlchemy

记得帮我点赞哦!

精心整顿了计算机各个方向的从入门、进阶、实战的视频课程和电子书,依照目录正当分类,总能找到你须要的学习材料,还在等什么?快去关注下载吧!!!

朝思暮想,必有回响,小伙伴们帮我点个赞吧,非常感谢。

我是职场亮哥,YY 高级软件工程师、四年工作教训,回绝咸鱼争当龙头的斜杠程序员。

听我说,提高多,程序人生一把梭

如果有幸能帮到你,请帮我点个【赞】,给个关注,如果能顺带评论给个激励,将不胜感激。

职场亮哥文章列表: 更多文章

自己所有文章、答复都与版权保护平台有单干,著作权归职场亮哥所有,未经受权,转载必究!

退出移动版