Flask的ORM和查询操作

Posted xujin247

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask的ORM和查询操作相关的知识,希望对你有一定的参考价值。

Flask 的ORM

SQLAlchemy

SQLAlchemy是Python编程语言下的一个嵌入式软件。提供了SQL工具包以及对象关系映射(ORM)工具。

SQLAlchemy“采用简单的Python语言,为高效和高级的数据库访问设计,实现完整的企业级持久模型”。

SQLAlchemy首次发行于2006年2月,并迅速地在Python社区中最广泛使用的ORM工具之一,不亚于Django的ORM框架。

Flask-SQLAlchemy

Flask-SQLAlchemy是在Flask框架的一个扩展中,其对SQLAlchemy进行了封装,目的在于简化在Flask中。SQLAlchemy的使用,提供了有用的替代价值和额外的助手来简化简单地完成日常任务

映射关系

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)


class Config(object):
    SQLALCHEMY_DATABASE_URI = mysql://root:mysql@127.0.0.1:3306/toutiao
    ‘‘‘
    Postgres:
    postgresql://user:password@localhost/mydatabase
    
    MySQL:
    mysql://user:password@localhost/mydatabase
    
    Oracle:
    oracle://user:password@127.0.0.1:1521/sidname
    
    SQLite (注意开头的四个斜线):
    sqlite:////absolute/path/to/foo.db
    ‘‘‘
    SQLALCHEMY_TRACK_MODIFICATIONS = False #在Flask中是否追踪数据修改
    SQLALCHEMY_ECHO = False #显示生成的sql语句


app.config.from_object(Config)#向工程中导入配置

db = SQLAlchemy(app) #创建连接对象

class User(db.Model):
    """
    用户基本信息
    """
    __tablename__ = user_basic#在数据库中的表名

    class STATUS:#创建一个储存常量的类 方便下面使用
        ENABLE = 1
        DISABLE = 0

    id = db.Column(user_id, db.Integer, primary_key=True, doc=用户ID)#如果在库中的字段名想和模型类中的不一样 可以在这里重新设置 
    mobile = db.Column(db.String, doc=手机号)#这里不重新设置 就默认相同
    password = db.Column(db.String, doc=密码)
    name = db.Column(user_name, db.String, doc=昵称)
    profile_photo = db.Column(db.String, doc=头像)
    last_login = db.Column(db.DateTime, doc=最后登录时间)
    is_media = db.Column(db.Boolean, default=False, doc=是否是自媒体)
    is_verified = db.Column(db.Boolean, default=False, doc=是否实名认证)
    introduction = db.Column(db.String, doc=简介)
    certificate = db.Column(db.String, doc=认证)
    article_count = db.Column(db.Integer, default=0, doc=发帖数)
    following_count = db.Column(db.Integer, default=0, doc=关注的人数)
    fans_count = db.Column(db.Integer, default=0, doc=被关注的人数(粉丝数))
    like_count = db.Column(db.Integer, default=0, doc=累计点赞人数)
    read_count = db.Column(db.Integer, default=0, doc=累计阅读人数)
    account = db.Column(db.String, doc=账号)
    email = db.Column(db.String, doc=邮箱)
    status = db.Column(db.Integer, default=1, doc=状态,是否可用)

操作

新增

from db_demo import app,db,User
user = User(mobile=13112345678,name= 小红)
db.session.add(user)#这个session是临时保存上传数据用的
db.session.commit()

也可以批量添加

db.session.add_all([user1,user2,user3])
db.session.commit()

删除

第一种

  user = User.query.order_by(User.id.desc()).first()
  db.session.delete(user)
  db.session.commit()

第二种

  User.query.filter(User.mobile=18512345678).delete()
  db.session.commit()

修改

第一种

  user = User.query.get(1)
  user.name = Python
  db.session.add(user)
  db.session.commit()

第二种

  User.query.filter_by(id=1).update({name:python})
  db.session.commit()

 

查询

User.query.all()#查询所有 返回列表
User.query.first() #查询第一个   返回对象
User.query.get(2) #根据主键id获取对象 如果没有则返回None

原生SQLAlchemy查询语句
db.session.query(User).all()
db.session.query(User).first()
db.session.query(User).get(2)

过滤查询

filter_by#只能查查询条件是 =  和and的 其他功能要用filter

User.query.filter_by(id=1)
#<flask_sqlalchemy.BaseQuery object at 0x7f6d9edbb630>
User.query.filter_by(id=1).first()
#<User 1>
User.query.filter_by(id=1).all()
#[<User 1>]
User.query.filter_by(mobile=13911111111, id=1).first()  # and关系

两者区别 filter 里面的参数还要加模型类.属性
     filter 里的等于是==
filter User.query.filter(User.mobile==13911111111).first()
User.query.filter(User.id
>10).all() #[<User 11>, <User 12>, <User 13>, <User 14>, <User 15>, <User 16>...] from sqlalchemy import or_,not_,and_ User.query.filter(or_(User.id>10,User.mobile==13173686247)).all()

模糊查询

User.query.filter(User.mobile.startswith(131)).all()

相当于sql语句里的

select * from User where mobile like 131%;

 

offset

偏移,起始位置

User.query.offset(2).all()

limit

获取限制数据

User.query.limit(3).all()

合起来使用

User.query.offset(6).limit(3).all()
#[<User 7>, <User 8>, <User 9>]

相当于sql语句里的

select * from User limit 6,3;

order_by

排序

User.query.order_by(User.id).all()  # 正序
User.query.order_by(User.id.desc()).all()  # 倒序

相当于sql语句中的

select * from User order by id asc;
select * from User order by id desc;

优化查询

有的时候我们并不需要查出所有字段 查出的无用数据反而会造成资源浪费

from sqlalchemy.orm import load_only

User.query.options(load_only(User.name,User.mobile)).filter_by(id=1).first()#查询特定字段  options 选项

聚合查询

from sqlalchemy import func

db.session.query(表.关注者,func.count(表.被关注者)).group_by(表.关注者)

返回一个列表 [(1,3),(2,4),(4,5)] ————>一号用户关注了三个 二号用户关注了四个 四号用户关注了五个
#例子 查询用户关注表 中 每个用户关注了几个用户 select 关注者 count(被关注者) from 表 group by 关注者;

关联查询

1. 使用ForeignKey
class User(db.Model):
    ...
    profile = db.relationship(UserProfile, uselist=False)
    followings = db.relationship(Relation)

class UserProfile(db.Model):
    id = db.Column(user_id, db.Integer, db.ForeignKey(user_basic.user_id), primary_key=True,  doc=用户ID)
    ...

class Relation(db.Model):
    user_id = db.Column(db.Integer, db.ForeignKey(user_basic.user_id), doc=用户ID)
    ...

# 测试   
user = User.query.get(1)
user.profile.gender
user.followings
2. 使用primaryjoin
class User(db.Model):
    ...

    profile = db.relationship(UserProfile, primaryjoin=User.id==foreign(UserProfile.id), uselist=False)
    followings = db.relationship(Relation, primaryjoin=User.id==foreign(Relation.user_id))

# 测试
user = User.query.get(1)
user.profile.gender
user.followings
3. 指定字段关联查询
class Relation(db.Model):
    ...
    target_user = db.relationship(User, primaryjoin=Relation.target_user_id==foreign(User.id), uselist=False)

from sqlalchemy.orm import load_only, contains_eager

Relation.query.join(Relation.target_user).options(load_only(Relation.target_user_id), contains_eager(Relation.target_user).load_only(User.name)).all()

事务

???

以上是关于Flask的ORM和查询操作的主要内容,如果未能解决你的问题,请参考以下文章

flask ORM操作方法

快速入门流行ORM框架~Flask-SQLAlchemy

Flask-SQLAlchemy精确查询&模糊查询---ORM(1)

flask 中orm关系映射 sqlalchemy的查询

Flask ORM SQLAlchemy数据操作完整案例

Flask ORM SQLAlchemy数据操作完整案例