zoukankan      html  css  js  c++  java
  • Flask学习之旅--还是数据库(sqlacodegen + SQL Alchemy)

    一、写在前面

      其实之前已经写过一篇关于 Flask 中使用数据库的博客了,不过那一篇博客主要是记录我在使用 Flask + MySQL8.0 时所遇到的一些问题(如果用的不是 MySQL8.0估计就没有这么多问题了!)。然后这一篇可以算作一份学习笔记了,也是关于在 Flask 中进行数据库操作的,感觉写这种学习笔记还是比较有用的,可以再学习一遍也就能更好的掌握了。

      在使用 Flask 的时候,一般都会创建一个 model.py,然后在里面继承和创建模型,再迁移到数据库中,最后进行一些增删改查等操作。但是如果数据库表已经建立好了呢?有没有办法将这些数据库表引入到 Flask 中呢?

    二、sqlacodegen

    1.sqlacodegen简介

      sqlacodegen pypi:https://pypi.org/project/sqlacodegen/

      其中对 sqlacodegen 的介绍是:这是一个工具,它读取现有数据库的结构并生成相应的 SQLAlchemy 模型代码,如果可能,使用声明式样式。

      sqlacodegen 的几个主要特性为:

      1)支持 SQLAlchemy 0.8.x - 1.3.x。

      2)生成几乎看起来像是手写的声明性代码。

      3)生成符合 PEP 8 标准的代码。

      4)准确地确定关系,包括多对多,一对一。

      5)自动检测连接表继承。

    2.sqlacodegen安装

      使用 pip 安装即可:

    pip install sqlacodegen

    3.sqlacodegen用法

      下面是一个 sqlacodegen 用法示例:

    sqlacodegen mysql+pymysql://root:qwer1234@127.0.0.1/mydb --tables users,roles,phone >models.py

       首先是一个 sqlacodegen 命令,后面接上连接数据库的语句,然后可以使用 --tables 指定要导入的数据表,最后用 >models.py 输出到 models.py 中,如果不指定输出文件,会将 python 代码直接打印出来。下面是生成的 models.py 中的代码:

     1 # coding: utf-8
     2 from sqlalchemy import Column, ForeignKey, String
     3 from sqlalchemy.dialects.mysql import INTEGER
     4 from sqlalchemy.orm import relationship
     5 from sqlalchemy.ext.declarative import declarative_base
     6 
     7 Base = declarative_base()
     8 metadata = Base.metadata
     9 
    10 
    11 class Phone(Base):
    12     __tablename__ = 'phone'
    13 
    14     phone = Column(String(11), primary_key=True)
    15     phone_address = Column(String(40))
    16 
    17 
    18 class Role(Base):
    19     __tablename__ = 'roles'
    20 
    21     role_id = Column(INTEGER(11), primary_key=True)
    22     role_name = Column(String(45))
    23 
    24 
    25 class User(Base):
    26     __tablename__ = 'users'
    27 
    28     user = Column(String(10), primary_key=True)
    29     sex = Column(String(10))
    30     email = Column(String(45))
    31     phone = Column(String(11))
    32     role_id = Column(ForeignKey('roles.role_id'), index=True)
    33 
    34     role = relationship('Role')

    三、SQL Alchemy

    1.SQL Alchemy简介

      SQL Alchemy pypi:https://pypi.org/project/SQLAlchemy/

      SQL Alchemy 是 Python SQL 工具包和对象关系映射器,它为应用程序开发人员提供了SQL的全部功能和灵活性。

      在写上篇博客的时候简单介绍过 Flask-SQLAlchemy,当时说到它将对 SQL Alchemy 的支持添加到 Flask 应用程序中,因此我们通过简单设置之后就能在 Flask 中队数据库进行操作了,可那是当我们在把定义好的模型映射到数据库中时所用的。如果数据库表已经建好了,还怎么用 Flask-SQLAlchemy 来操作呢?这时候就需要使用 SQL Alchemy 了!

    2.SQL Alchemy安装

      使用 pip 安装即可:

    pip install SQLAlchemy

    3.SQL Alchemy架构

      

      1)Schema / Types 定义了类到表之间的映射框架(规则)。

      2)SQL Expression Language 封装好的 SQL 语句。

      3)Engine 操作者。

      4)Connection Pooling 连接池。

      5)Dialect 根据用户的配置,调用不同的数据库 API(如:Mysql) 并执行对应的 SQL 语句。

    4.SQL Alchemy用法

    (1)连接数据库

    1 from sqlalchemy import create_engine
    2 
    3 
    4 engine = create_engine("mysql+pymysql://root:qwer1234@127.0.0.1:3306/mydb")

      create_engine() 会返回一个引擎实例,它代表着数据库的接口。这个引擎实例可以执行 SQL 语句,例如:

    engine.execute("show tables")

    (2)创建会话

       光有这个数据库的引擎还不够,还需要建立会话才行,这里要使用引擎来创建一个 Session 类的实例,代码为:

     1 from sqlalchemy import create_engine
     2 from sqlalchemy.orm import sessionmaker
     3 
     4 
     5 # 创建引擎
     6 engine = create_engine("mysql+pymysql://root:qwer1234@127.0.0.1:3306/mydb")
     7 # 使用引擎创建Session
     8 DB_Session = sessionmaker(bind=engine)
     9 # 实例化
    10 db_session = DB_Session()

    (3)单表 CRUD

      插入数据:

    1 # 插入
    2 db_session.execute("insert into roles values(%d,%s)" % (1, "'admin'"))
    3 db_session.execute("insert into users values(%s,%s,%s,%s,%d)" % ("'user1'", "'man'", "'user1@163.com'", "'12233445566'", 1))
    4 db_session.commit()

      插入数据可以使用 SQL 语句来完成,在插入数据之后要使用 commit(),这一点不能忘记。

      查询数据:

    1 # 查询
    2 result = db_session.query(User).filter(User.user == "user1")
    3 print(result.all())
    4 usr = result.all()[0]
    5 print(usr.email)
    6 
    7 # [<SQlAlchemy.models.User object at 0x0000028D33D7CDD8>]
    8 # user1@163.com

      在查询的时候需要使用 query()  和 filter(),返回的结果是一个列表,如果列表为空就表示数据库中没有该记录。对于返回的这个结果,使用 all() 返回所有记录,使用 one() 返回第一条记录。

      更新数据:

    1 # 更新
    2 db_session.query(User).filter(User.user == "user1").update({User.email: 'user1user1@163.com'})
    3 db_session.commit()
    4 # 查询
    5 result = db_session.query(User).filter(User.user == "user1")
    6 usr = result.one()
    7 print(usr.email)
    8 
    9 # user1user1@163.com

      更新数据可以使用 update() 方法,不过要接在 filter() 之后,使用这种方法即使数据库中没有记录也不会报错。

      删除数据:

    1 # 删除
    2 db_session.query(User).filter(User.user == "user1").delete()
    3 # 查询
    4 result = db_session.query(User).filter(User.user == "user1")
    5 usr = result.one()
    6 print(usr.email)
    7 
    8 # sqlalchemy.orm.exc.NoResultFound: No row was found for one()

      删除数据的使用方法和更新数据类似,只不过是在 filter() 之后使用 delete() 方法。

    (4)多表查询

       假设要查询 phone 为"12233445566"的用户名称和电话所在地址,就需要将 users 表和 phone 表联合起来进行查询,方法是使用多个 filter():

    1 res = db_session.query(User, Phone).filter(User.phone == "12233445566").filter(Phone.phone == "12233445566")
    2 u, p = res.one()
    3 print(u.user, p.phone_address)
    4 
    5 # user1 A

      假设要查询 user 为"user1"的用户的角色信息,就需要将 users 表和 roles 表联合起来进行查询,因为有外键的关系,所以可以使用 join():

    1 res = db_session.query(User).join(Role).filter(User.user == "user1")
    2 u = res.one()
    3 print(u.user, u.role.role_name)
    4 
    5 # user1 admin
  • 相关阅读:
    [struts2学习笔记] 第一节 关于struts2的简单认知
    OpenCV——RGB三通道分离
    [shiro学习笔记]第三节 使用myeclipse导入apache shiro中的QuikStart example例子
    [maven学习笔记]第一节,认识maven,搭建maven开发环境,写第一个HelloWorld
    [shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证
    PS 滤镜——运动模糊
    PS 滤镜——素描算法(二)
    [ExtJS5学习笔记]第二十四节 Extjs5中表格gridpanel或者表单数据后台传输remoteFilter设置
    BZOJ_1798_[AHOI2009]维护序列_线段树
    BZOJ_2001_[BeiJing2006]狼抓兔子_最小割转对偶图
  • 原文地址:https://www.cnblogs.com/TM0831/p/11555345.html
Copyright © 2011-2022 走看看