Flask-模型操作

创建模型

...

字段类型

类型名 Python类型 说明
Integer int 普通整数,一般是32位
SmallInteger int 取值范围小的整数,一般是16位
BigInteger int 或 long 不限制精度的整数
Float float 浮点数
Numeric decimal.Decimal 定点数
String str 变长字符串
Text str 长字符串,对较长或不限长度的字符串做了优化
Unicode unicode 变长Unicode字符串
UnicodeText unicode 变长Unicode字符串,对较长或不限长度的字符串做了优化
Boolean bool 布尔值
Date datetime.date 日期
Time datetime.time 时间
DateTime datetime.datetime 日期和时间
Interval detetime.timedelta 时间间隔
LargeBinary str 二进制文件

常用约束

选项名 说明
primary_key
unique
index
nullable
default

模型操作

单表操作

增加数据
  a、一次增加一条数据:
    p = Person()
    p.name = '小明'
    p.age = 22

    try:
      db.session.add(p)
      db.session.commit()
    except:
      # 回滚
      db.session.rollback()
      db.session.flush()

  b、一次添加多条数据
    persons = []
    for i in range(10,30):
      p = Person()
      p.name = 'baoqiang' + str(i)
      p.age = i
      persons.append(p)

    db.session.add_all(persons)
# 增:
@blue.route('/useradd/')
def uesr_add():
    # u = User()
    # u.name = 'kum'
    # u.age = 22
    # db.session.add(u)  # 将u对象添加到session中
    # db.session.commit() # 同步到数据库中

    users = []
    for i in range(10,30):
        u = User()
        u.name = 'bingbing' + str(i)
        u.age = i
        users.append(u)
    try:
        db.session.add_all(users)
        db.session.commit() # 事务提交
    except Exception as e:
        db.session.rollback() # 回滚
        db.session.flush() # 刷新,清空缓存
        return 'fail:' + str(e)
    return 'success!'

#删
@blue.route('/userdel/')
def user_del():
    u = User.query.first() #查询第一条数据
    db.session.delete(u)
    db.session.commit()
    return 'success!'

#改
@blue.route('/userupdate/')
def user_update():
    u = User.query.first()
    u.age = 100
    db.session.commit()
    return 'success!'

过滤器
	filter()	把过滤器添加到原查询上,返回一个新查询
	filter_by()	把等值过滤器添加到原查询上,返回一个新查询

	limit()		使用指定的值限制原查询返回的结果数量,返回一个新查询
	offset()	偏移原查询返回的结果,返回一个新查询
	order_by()	根据指定条件对原查询结果进行排序,返回一个新查询
	group_by()	根据指定条件对原查询结果进行分组,返回一个新查询

常用查询
	all()	以列表形式返回值查询的所有结果,返回列表
	first()	返回查询的第一个结果,如果没有结果,则返回None
	first_or_404()	返回查询的第一个结果,如果没有结果,则终止请求,返回404错误响应
	get()	返回指定主键对应的行,如果没有对应的行,则返回None
	get_or_404()	返回指定主键对应的行,如果没找到指定的主键,则终止请求,返回404错误响应
	count()	返回查询结果的数量
	paginate()	返回一个Paginate对象,它包含指定范围内的结果

	查询属性
    	contains
    	startswith
    	endswith
    	in_
        __gt__
    	__ge__
    	__lt__
    	__le__

	逻辑运算
    	与 and_
        	filter(and_(条件),条件...)
    	或 or_
        	filter(or_(条件),条件...)
    	非 not_
        	filter(not_(条件),条件...)

	示例:
    	查询:
        	persons = Person.query.all()
        	persons = Person.query.filter(Person.age=>22)

        	# filter功能比filter.by强大
        	persons = Person.query.filter(Person.age==22) # filter(类.属性==值)
        	persons = Person.query.filter_by(age=22) # filter_by(属性=值)

        	persons = Person.query.filter(Person.age.__lt__(22)) # <
        	persons = Person.query.filter(Person.age.__le__(22)) # <=
            persons = Person.query.filter(Person.age.__gt__(22)) # >
        	persons = Person.query.filter(Person.age.__ge__(22)) # >=

        	persons = Person.query.filter(Person.age.startswith('宝'))
        	persons = Person.query.filter(Person.age.endswith('宝'))
        	persons = Person.query.filter(Person.age.contains('宝'))
        	persons = Person.query.filter(Person.age.in_((11,12,22)))

        	persons = Person.query.filter(Person.age>=20, Person.age<30) # and_
        	persons = Person.query.filter(and_(Person.age>=20, Person.age<30)) # and_
        	persons = Person.query.filter(or_(Person.age>=30, Person.age<20)) # or_
        	persons = Person.query.filter(not_(Person.age<30)) # not_

    	排序:
        	persons = Person.query.order_by('age') # 升序
        	persons = Person.query.order_by(desc('age')) # 降序
    	分页:
        	persons = Person.query.limit(5) # 取前5个
        	persons = person.query.offset(5) # 跳过前5个

        	# 获取页码page和每页数量num
            page = int(request.args.get('page'))
        	per_page = int(request.args.get('per_page'))

        	# 手动做分页
        	persons = Person.query.offset((page - 1) * per_page).limit(per_page)

        	# 使用paginate做分页
            persons = Person.query.paginate(page=page, per_page=per_page, error_out=False).items

    	paginate对象的属性:
        	items:返回当前页的内容列表
        	has_next: 是否还有下一页
        	has_prev: 是否还有上一页
        	next(error_out=False): 返回下一页的Pagination对象
            prev(error_out=False): 返回上一页的Pagination对象
        	page: 当前页的页码(从1开始)
        	pages:总页数
        	per_page: 每页显示的数量
        	prev_num:	上一页页码数
        	next_num:	下一页页码数
        	query:	返回创建该pagination对象的查询对象
        	total:	查询返回的记录总数

03-模型进阶

多表关联

一对多

class Grade(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(16))
    # 定义班级表的一对多关系,不是字段,Student为学生表模型,backref为反向查找名称
    # 建立关联
    #   第一个参数:关联的模型名(表)
    #   第二个参数:反向引用的名称,grade对象,让student去反过来得到grade对象的名称
    #   第三个参数:懒加载
    # 这里的students不是字段
    students = db.relationship('Student', backref='grade', lazy=True)

class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(16))
    age = db.Column(db.Integer, default=1)
    # 创建外键,关联到班级表的主键,实现一对多关系,班级表中也要有对应操作
    gradeid = db.Column(db.Integer, db.ForeignKey(Grade.id))


查:
# 获取学生的所在班级信息(反向)
	stu = Student.query.get(stuid)
	grade = stu.stus
# 获取班级的所有学生(正向)
	grade = Grade.query.get(gradeid)
	students = grade.students

删:
# 获取班级的所有学生(正向)
	grade = Grade.query.get(id)
	db.session.delete(grade)
	db.session.commit()

多对多

用户收藏电影,一个用户可以收藏多部电影,一部电影可以被不同的用户收藏,是一个多对多关系

# 中间表(不是类)
collect = db.Table('collects',
                    # user_id为表字段名称,user.id为外键表的id
                    db.Column('user_id',db.Integer, db.ForeignKey('usermodel.id'), primary_key=True),
                    db.Column('movie_id', db.Integer, db.ForeignKey('moviemodel.id'), primary_key=True)
                   )
# 将user_id、movie_id同时设置为primary_key,即两个值联合唯一

# 用户表
class UserModel(db.Model):
    __tablename__ = 'usermodel'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(30), unique=True)
    age = db.Column(db.Integer, default=1)


# 电影表
class MovieModel(db.Model):
    __tablename__ = 'movie'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(30))
    # 关联
    # secondary = collect: 设置中间表
    users = db.relationship('UserModel', backref='movies', lazy=True, secondary=collect)


lazy属性:
	懒加载,可以延迟在使用关联属性的时候才建立关联
    	lazy='dynamic': 会返回一个query对象(查询集),可以继续使用其它查询方法:如all().
    	lazy='select': 首次访问到属性的时候,就会全部加载该属性的数据
    	lazy='joined': 在对关联的两个表进行join操作,从而获取到所有相关的对象
    	lazy=True: 返回一个可用的列表对象,同select

查:
	# 查询用户收藏的所有电影
	user = User.query.get(id)
	movies = user.movies

	# 查询电影被哪些用户收藏
	movie = Movie.query.get(id)
	users = movie.users

删:
	# 中间表的数据会被级联删除
	movie = Movie.query.get(id)
	db.session.delete(movie)
	db.session.commit()

增:
	# 用户收藏电影
	user = User.query.get(id)
	movie = Movie.query.get(id)
	user.movies.append(movie)
	db.session.commit()

作业:图书馆项目

创建一个项目,用来说明出版社,书籍和作者的关系。
假定关系:	作者:书籍 => 1:n (一本书由一个作者完成,一个作者可以创作多本书)
        	出版社:书籍 => n:n (一个出版社可以出版多本书,一本书可以由多个出版社出版)
要求:
	1、在书籍的book_index.html中有一个’查看所有书籍‘的超链接按钮,点击进入书籍列表
book_list.html页面。
	2、在书籍的book_list.html中显示所有书名,点击书名可以进入书籍详情book_detail.html。
	3、在书籍book_detail.html中可以点击该书的作者和出版社,进入作者详情的author_detail.html和
出版社详情的publisher_detail.html页面

# 作者
class Author(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(20), unique=True)
    age = db.Column(db.Integer, default=1)
    sex = db.Column(db.Boolean, default=True)
    email = db.Column(db.String(200))
    # 关系
    books = db.relationship('Book', backref='my_author', lazy='dynamic')

# 书籍
class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), unique=True)
    date = db.Column(db.DateTime)
    # 1对多,外键
	authorid = db.Column(db.Integer, db.ForeignKey(Author.id))

# 中间表(书籍-出版社)
book_publisher = db.Table('book_publisher',
            db.Column('book_id', db.Integer, db.ForeignKey('book.id'), primary_key=True),
            db.Column('publisher_id', db.Integer, db.ForeignKey('publsher.id'), primary_key=True)
        )

# 出版社
class Publisher(db.Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
	name = db.Column(bd.String(20), unique=True)
	address = db.Column(db.String(200))
	city = db.Column(db.String(100))
	provice = db.Column(db.String(100))
	country = db.Column(db.String(100))
	website = db.Column(db.String(100))
	# 多对多,关联book表
	books = db.relationship('Book', backref='publishers', 
                            secondary=book_publisher, lazy='dynamic')
posted @   Bruce_JRZ  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示