zoukankan      html  css  js  c++  java
  • sqlalchemy的基本用法

      参考原文:https://www.cnblogs.com/blueberry-mint/p/14277882.html

      1 简介

      SQLAlchemy是用Python编程语言开发的一个开源项目。它提供了SQL工具包和ORM(对象关系映射)工具,使用MIT许可证发行。

      SQLAlchemy最初在2006年2月发行,发行后便很快的成为Python社区中最广泛使用的ORM工具之一,丝毫不亚于Django自带的ORM框架。

      SQLAlchemy采用简单的Python语言,提供高效和高性能的数据库访问,实现了完整的企业级持久模型。它的理念是,SQL数据库的量级和性能比对象集合重要,而对象集合的抽象又重要于表和行。

      2 基本用法

      2.1 安装

      安装sqlachemy

    pip3 install sqlalchemy
    pip3 install pymysql
    

      本文使用MySQL作为数据库,使用pymysql作为驱动,因此需要安装pymysql

      2.2 连接数据库

      配置信息

      在连接数据库前,需要使用到一些配置信息,然后把它们组合成满足以下条件的字符串:

    dialect+driver://username:password@host:port/database
    

      

    • dialect:数据库,如:sqlite、mysql、oracle等
    • driver:数据库驱动,用于连接数据库的,本文使用pymysql
    • username:用户名
    • password:密码
    • host:IP地址
    • port:端口
    • database:数据库

      建议将这些配置信息放到一个配置文件中,如config.py然后倒入配置文件

      config.py

    HOST = '192.168.1.180'
    PORT = 3306
    USERNAME = 'root'
    PASSWORD = 'password'
    DB = 'myclass'
    
    # f代表可以使用{}引用变量
    DB_URI = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DB}'
    # 以下语句和上面语句作用一致
    # DB_URI = 'mysql+pymysql://%s:%s@%s:%s/%s'%(USERNAME,PASSWORD,HOST,PORT,DB)
    

      创建引擎并连接数据库

      注意:本次操作的数据库名为myclass需要提前创建好

    from sqlalchemy import create_engine
    from config import DB_URI
    
    
    engine = create_engine(DB_URI)  # 创建引擎
    conn = engine.connect()  # 连接
    result = conn.execute('SELECT 1')  # 执行SQL
    print(result.fetchone())  
    conn.close()  # 关闭连接
    

      这里执行是SQL语句可以参考 https://www.cnblogs.com/minseo/p/15291725.html 是一致的

      创建ORM模型并映射到数据库中

    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import create_engine, Column, Integer, String
    from sqlalchemy.orm import sessionmaker
    from config import DB_URI
    # print(DB_URI)
    # mysql+pymysql://root:password@192.168.1.180:3306/myclass
    # 创建引擎
    engine = create_engine(DB_URI)
    #sconn = engine.connect()
    # 创建SQLORM基类,注意这里要加参数,参数为上一步创建的引擎
    Base = declarative_base(engine)
    # 构建session对象
    session = sessionmaker(engine)()
    
    # 创建student表
    # 该表有4列分别为自增id name age sex
    # 分别代表id 姓名 年龄 性别其中id age为整数 name和sex为字符串
    class Student(Base):
        __tablename__ = 'student'  # 表名
        id = Column(Integer, primary_key=True, autoincrement=True)
        name = Column(String(50))
        age = Column(Integer)
        sex = Column(String(10))
    
    # 将模型映射到数据库中
    # 即如果数据库中没有student表则创建映射表student
    Base.metadata.create_all()
    

      执行上面代码,将会在数据库中生成对应的映射表student 

      可以登录MySQL查看建表语句

    mysql> show create table student;
    +---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Table   | Create Table                                                                                                                                                                                                                                    |
    +---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | student | CREATE TABLE `student` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(50) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `sex` varchar(10) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 
    

      注意:如果表结构有修改,例如增加一个字段address

    address = Column(String(100))
    

      再执行不会修改表,只有删除表再执行才会重新创建表并且新增这个字段

      即执行Base.metadata.create_all()是如果数据库里面没有表则创建表,如果有表则不进行操作

      新增数据

      在添加数据之前可以把以下代码注释,因为表已经创建好了,无需执行

    Base.metadata.create_all()
    

      

      创建好表以后,接下来我们要添加数据,代码如下  

    # 新增数据
    # 创建一个Student对象
    student = Student(name='Tony',age=18,sex='male')
    # 添加到session
    session.add(student)
    # 提交到数据库
    session.commit()
    

      添加数据以后查看

    mysql> select * from student;
    +----+------+------+------+
    | id | name | age  | sex  |
    +----+------+------+------+
    |  1 | Tony |   18 | male |
    +----+------+------+------+
    

      也可以批量添加数据

    # 批量添加数据
    # 使用add_all()方法传递的参数为list
    # list对象为Student对象
    session.add_all([
        Student(name='Jane', age=16, sex='female'),
        Student(name='Ben', age=20, sex='male')
    ])
    session.commit()
    

      查询数据库现在有3条数据了

    mysql> select * from student;
    +----+------+------+--------+
    | id | name | age  | sex    |
    +----+------+------+--------+
    |  1 | Tony |   18 | male   |
    |  2 | Jane |   16 | female |
    |  3 | Ben  |   20 | male   |
    

      查询数据

      sqlalchemy提供了query()方法来查询数据

      获取所有数据

    # 查询数据
    # 获取所有数据
    item_list = session.query(Student).all()
    # 获取的是Student对象
    print(item_list)
    # [<__main__.Student object at 0x000002748DEC2BE0>, <__main__.Student object at 0x000002748DEC2C50>, <__main__.Student object at 0x000002748DEC2CC0>]
    # 遍历通过对象的属性打印对应的数据
    for item in item_list:
        print(item.name, item.age)
    # Tony 18
    # Jane 16
    # Ben 20
    

      查询得到的item_list是一个包含多个Student对象的列表

      指定列查询

    # 指定列查询
    # 指定查询name列
    # 类似于执行sql语句select name from student;
    item_list = session.query(Student.name).all()
    # 查询的数据组成一个list,数据为元组为查询的结果
    # 可以指定多个列以,分隔,获取的结果的元组也以,分隔
    print(item_list)
    # [('Tony',), ('Jane',), ('Ben',)]
    

      获取返回数据的第一行

    # 获取返回数据的第一行
    item = session.query(Student.name).first()
    print(item)
    # ('Tony',)
    

      使用filter()方法过滤

    # 使用filter方法过滤
    item_list = session.query(Student.name).filter(Student.age >= 18).all()
    print(item_list)
    
    # [('Tony',), ('Ben',)]
    

      使用order_by()进行排序

    # 使用order_by()进行排序
    # 使用列name和age查询并且使用age进行倒序
    item_list = session.query(Student.name,Student.age).order_by(Student.age.desc()).all()
    print(item_list)
    # [('Ben', 20), ('Tony', 18), ('Jane', 16)]
    

      多条件查询

    # 多条件查询条件以,分隔默认为and
    item_list = session.query(Student.name, Student.age, Student.sex).filter(Student.age >= 10, Student.sex == 'female').all()
    print(item_list)
    

      以上查询语句类似于sql语句

    mysql> select name,age,sex from student where age<=16 and sex='female';
    +------+------+--------+
    | name | age  | sex    |
    +------+------+--------+
    | Jane |   16 | female |
    +------+------+--------+
    1 row in set (0.00 sec)
    

      使用or_连接多个条件

    # 以or条件查询
    # 需要导入or_
    from sqlalchemy import or_
    item_list = session.query(Student.name,Student.age,Student.sex).filter(or_(Student.age >=20,Student.sex=='female')).all()
    print(item_list)
    # [('Jane', 16, 'female'), ('Ben', 20, 'male')]
    

      equal/like/in

      下面示例查询等于,不等于,like是模糊查询,in是出现是否包含传递参数列表类元素

    # equal/like/in
    # 等于 查询age等于18的对象
    item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age==18).all()
    print(item_list)
    # [('Tony', 18, 'male')]
    
    # 不等于
    item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age != 18).all()
    print(item_list)
    # [('Jane', 16, 'female'), ('Ben', 20, 'male')]
    
    # like
    # 查询名字有有To字符的对象
    item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.name.like('%To%')).all()
    print(item_list)
    # [('Tony', 18, 'male')]
    
    # in
    # 查询age为16或者20的对象,不是16到20的区间
    # 注意这里in后面有一个_符号
    item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age.in_([16,20])).all()
    print(item_list)
    # [('Jane', 16, 'female'), ('Ben', 20, 'male')]
    

      count计算个数

    # count计算个数
    count = session.query(Student).count()
    print(count)
    # 3
    

      切片

    # 切片,和Python切片方法一样
    item_list = session.query(Student.name).all()[:2]
    print(item_list)  
    # [('Tony',), ('Jane',)]
    

      修改数据

       修改数据可以使用update()方法,update完成后记得执行session.commit()

    # 修改数据
    # 把Tony的age修改为22
    # 先查询对象,filter设置过滤条件,update修改数据
    session.query(Student).filter(Student.name=='Tony').update({'age':22})
    session.commit()

      删除数据

       删除数据使用delete()方法,同样也需要执行session.commit()提交事务

    # 删除数据
    session.query(Student).filter(Student.name=='Tony').delete()
    session.commit()
    

      注意:增删改查除了查询不设计修改操作,其他增删改都需要使用commit()方法提交事务

  • 相关阅读:
    谈一谈循环的性能提升
    Web前端性能优化的9大问题
    随机获取一种颜色值的三种方法
    ES6还是ES2015?
    history.back(-1)和history.go(-1)的区别
    关于overflow-y:scroll ios设备不流畅的问题
    前端如何压缩图片
    【转】理解JavaScript之闭包
    关于如何给数字排序
    本地缓存localstorage使用
  • 原文地址:https://www.cnblogs.com/minseo/p/15305003.html
Copyright © 2011-2022 走看看