flask学习笔记代码篇-14

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CSDNgaoqingrui/article/details/82557796

flask14-orm简介及数据库的基本操作


ORM

  • ORM 全拼Object-Relation Mapping.

  • 中文意为 对象-关系映射.

  • 主要实现模型对象到关系数据库数据的映射.

    • 比如:把数据库表中每条记录映射为一个模型对象

ORM图解

优点 :

  • 只需要面向对象编程, 不需要面向数据库编写代码.

    • 对数据库的操作都转化成对类属性和方法的操作.

    • 不用编写各种数据库的sql语句.

  • 实现了数据模型与数据库的解耦, 屏蔽了不同数据库操作上的差异.

    • 不在关注用的是mysqloracle...等.

    • 通过简单的配置就可以轻松更换数据库, 而不需要修改代码.

缺点 :

  • 相比较直接使用SQL语句操作数据库,有性能损失.

  • 根据对象的操作转换成SQL语句,根据查询的结果转化成对象, 在映射过程中有性能损失.

数据库连接设置

  • 在 Flask-SQLAlchemy 中,数据库使用URL指定,而且程序使用的数据库必须保存到Flask配置对象的 SQLALCHEMY_DATABASE_URI 键中

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:[email protected]:3306/test'

  • 其他设置:

# 动态追踪修改设置,如未设置只会提示警告

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True#查询时会显示原始SQL语句

app.config['SQLALCHEMY_ECHO'] = True

  • 其他配置

名字

备注

SQLALCHEMY_DATABASE_URI

用于连接的数据库 URI 。例如:sqlite:////tmp/test.dbmysql://username:password@server/db

SQLALCHEMY_BINDS

一个映射 binds 到连接 URI 的字典。更多 binds 的信息见用 Binds 操作多个数据库

SQLALCHEMY_ECHO

如果设置为Ture, SQLAlchemy 会记录所有 发给 stderr 的语句,这对调试有用。(打印sql语句)

SQLALCHEMY_RECORD_QUERIES

可以用于显式地禁用或启用查询记录。查询记录 在调试或测试模式自动启用。更多信息见get_debug_queries()。

SQLALCHEMY_NATIVE_UNICODE

可以用于显式禁用原生 unicode 支持。当使用 不合适的指定无编码的数据库默认值时,这对于 一些数据库适配器是必须的(比如 Ubuntu 上 某些版本的 PostgreSQL )。

SQLALCHEMY_POOL_SIZE

数据库连接池的大小。默认是引擎默认值(通常 是 5 )

SQLALCHEMY_POOL_TIMEOUT

设定连接池的连接超时时间。默认是 10 。

SQLALCHEMY_POOL_RECYCLE

多少秒后自动回收连接。这对 MySQL 是必要的, 它默认移除闲置多于 8 小时的连接。注意如果 使用了 MySQL , Flask-SQLALchemy 自动设定 这个值为 2 小时。

连接其他数据库

完整连接 URI 列表请跳转到 SQLAlchemy 下面的文档 (Supported Databases) 。这里给出一些 常见的连接字符串。

常用的SQLAlchemy字段类型

类型名

python中类型

说明

Integer

int

普通整数,一般是32位

SmallInteger

int

取值范围小的整数,一般是16位

BigInteger

int或long

不限制精度的整数

Float

float

浮点数

Numeric

decimal.Decimal

普通整数,一般是32位

String

str

变长字符串

Text

str

变长字符串,对较长或不限长度的字符串做了优化

Unicode

unicode

变长Unicode字符串

UnicodeText

unicode

变长Unicode字符串,对较长或不限长度的字符串做了优化

Boolean

bool

布尔值

Date

datetime.date

时间

Time

datetime.datetime

日期和时间

LargeBinary

str

二进制文件

常用的SQLAlchemy列选项

选项名

说明

primary_key

如果为True,代表表的主键

unique

如果为True,代表这列不允许出现重复的值

index

如果为True,为这列创建索引,提高查询效率

nullable

如果为True,允许有空值,如果为False,不允许有空值

default

为这列定义默认值

常用的SQLAlchemy关系选项

选项名

说明

backref

在关系的另一模型中添加反向引用

primary join

明确指定两个模型之间使用的联结条件

uselist

如果为False,不使用列表,而使用标量值

order_by

指定关系中记录的排序方式

secondary

指定多对多关系中关系表的名字

secondary join

在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结条件

makedata.py

from flask import Flask

from flask_sqlalchemy import SQLAlchemy



app = Flask(__name__)

# 配置数据库链接地址

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user1:[email protected]:3306/alchemy'

# 是否跟踪数据库的修改

app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False

# 初始化数据库操作对象

db = SQLAlchemy(app)


@app.route('/', methods=['post'])

def index():

    return '数据库链接'


# 角色

class Role(db.Model):

    __tablename__ = "roles"  # 指定表名,如果不指定会以类名的小写做为表名

    # 定义主键 id,默认会自增长

    id = db.Column(db.Integer, primary_key=True)

    # 角色的称呼

    name = db.Column(db.String(128), unique=True)

    # 可以直接通过当前类的对象.users 就可以访问到当前角色对应的所有用户

    # backref 反向引用,表示给其前面的类添加一个属性()

    # 在此表示给 User 这个类添加 role 的属性,以便能够直接通过 user.role 访问到一的这一方的数据



    # 定义 relationship 在一的这一方定义,第一个参数写多的这一方的类名,backref 写一的这一方的类名小写

    # 如果指定lazy='dynamic',只有在真正使用 users的时候(.first(), 遍历)orm才会帮我们去查询数据

    # backref=db.backref("role", lazy='dynamic'),

    users = db.relationship("User", backref="role", lazy='dynamic')


# 用户

class User(db.Model):

    __tablename__ = "users"

    # 主键

    id = db.Column(db.Integer, primary_key=True)

    # 用户名

    name = db.Column(db.String(128), unique=True)

    # 邮箱

    email = db.Column(db.String(128), unique=True)

    # 用户密码

    password = db.Column(db.String(128))

    # 外键-关联roles

    role_id = db.Column(db.INTEGER, db.ForeignKey('roles.id'))


def executive():

    try:

        db.drop_all()  # 删除表

        db.create_all()  # 创建表

        # 新增数据

        ro1 = Role(name="admin")

        ro2 = Role(name="user")

        db.session.add_all([ro1, ro2])

db.session.commit()

        # 修改数据

        # ro1 = Role(name='admin')

        # db.session.add(ro1)

        # 再次插入一条数据

        # ro2 = Role(name='user')

        # db.session.add(ro2)

        # 一次插入多条数据

        us1 = User(name='wang', email='[email protected]', password='123456', role_id=ro1.id)

        us2 = User(name='zhang', email='[email protected]', password='201512', role_id=ro2.id)

        us3 = User(name='chen', email='[email protected]', password='987654', role_id=ro2.id)

        us4 = User(name='zhou', email='[email protected]', password='456789', role_id=ro1.id)

        us5 = User(name='tang', email='[email protected]', password='158104', role_id=ro2.id)

        us6 = User(name='wu', email='[email protected]', password='5623514', role_id=ro2.id)

        us7 = User(name='qian', email='[email protected]', password='1543567', role_id=ro1.id)

        us8 = User(name='liu', email='[email protected]', password='867322', role_id=ro1.id)

        us9 = User(name='li', email='[email protected]', password='4526342', role_id=ro2.id)

        us10 = User(name='sun', email='[email protected]', password='235523', role_id=ro2.id)

        db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])

        # pass

    except Exception as e:

        print(e)

    else:

db.session.commit()


def local_query():

    try:

        User.query.all()

    except Exception as e:

        print(e)


if __name__ == '__main__':

    executive()

    app.run(debug=True)



"""

查询所有用户数据

    User.query.all()

查询有多少个用户

    User.query.count()

查询第1个用户

    User.query.first()

查询id为4的用户[3种方式]

    User.query.get(4)

    User.query.filter(User.id == 4).first()

    User.query.filter_by(id=4).first()

查询名字结尾字符为g的所有数据[开始/包含]

    User.query.filter(User.name.endswith('g')).all()

    # 开始 startswith

    # 包含 contains

查询名字不等于wang的所有数据[2种方式]

    User.query.filter(User.name != 'wang').all()

    from sqlalchemy import not_

    User.query.filter(not_(User.name == 'wang')).all()

查询名字和邮箱都以 li 开头的所有数据[2种方式]

    User.query.filter(User.name.startswith('li'), User.email.startswith('li')).all()

    from sqlalchemy import and_

    User.query.filter(and_(User.name.startswith('li'), User.email.startswith('li'))).all()

查询password是 `123456` 或者 `email` 以 `itheima.com` 结尾的所有数据

    User.query.filter(User.password == '123456', User.email.endswith('itheima.com')).all()

查询id为 [1, 3, 5, 7, 9] 的用户列表

    User.query.filter(User.id.in_([1,3,5,7,9])).all()

查询name为liu的用户所对应的角色数据

    role_id = User.query.filter(User.name == "liu").first().role_id

    Role.query.get(role_id)

查询所有用户数据,并以email排序

    # 默认是 asc() 顺序 倒序就是在属性后面调用 desc()

    User.query.order_by(User.email.desc()).all()

每页3个,查询第2页的数据

    # paginate 函数有三个参数,

        第1个表示查询第几页数据

        第2个表示每页多少个

        第3个如果有错是否抛出错误

        该函数的返回值是一个 paginate 对象



    paginate = User.query.paginate(2, 3, False)

    获取总页数

    paginate.pages

    获取当前页数

    paginate.page

    获取当前页数据

    paginate.items



查询name 为 admin这个角色所有的用户

    方式1:

        role = Role.query.filter(Role.name == "admin").first()

        User.query.filter(User.role_id == role.id).all()

    方式2:

        Role.query.filter(Role.name == "admin").first().users

    得到第二个用户 / 第n个用户的信息

        adminuser = Role.query.filter(Role.name == "admin").first().users

        adminuser[1]/ adminuser[n-1]



查询 id 为 3 所对应的角色

    方式1:

        role_id = User.query.filter(User.id == 3).first().role_id

        Role.query.get(role_id)

    方式2:

        User.query.filter(User.id == 3).first().role

    方式3:    

        User.query.get(3).role

"""

pycharm中使用Terminal做查询操作

猜你喜欢

转载自blog.csdn.net/CSDNgaoqingrui/article/details/82557796
今日推荐