flask数据库操作-flask_sqlalchemy(1)

本篇书书主要对以下几个方面提出简要看法

  • flask_sqlalchemy模块的安装和简单使用
  • flask_sqlalchemy对数据库的常规操作
  • 新知识拓展 - pypinyin模块的安装和简单使用

一.、flask_sqlalchemy

1. 了解flask_sqlalchemy

flask_sqlalchemy是一个第三方插件,需要安装。flask本身没有操作数据库的能力,需要借助flask_sqlalchemy对数据库进行操作。

2. 安装

1) 在pycharm的terminal中进行安装:pip install flask_sqlalchemy
2) 或者在命令行进行安装:pip install flask_sqlalchemy
注意:如果使用的是沙箱环境,需要激活沙箱环境:activate 环境名称

3. 使用

在本篇书书中,我们使用的是sqllite这种轻量级的关系型数据库。sqllite数据库是和python最契合的数据库,所以在安装python的同时已经携带了sqllite数据库,所以我们不需要进行安装就可以使用。

1) 导入模块

from flask_sqlalchemyimport SQLAlchemy

2) 配置和加载数据库

# base_dir:当前文件的路径
# os.path.dirname:返回指定文件的目录
# __file__:指当前文件
# abspath:是绝对路径
# print(base_dir): E:\Python\flaskPro_ORM
base_dir = os.path.dirname(
        os.path.abspath(__file__)
)

# 创建http实例
app = Flask(__name__)
# 数据库存放的路径
app.config["SQLALCHEMY_DATABASE_URI"] ="sqlite:///" + os.path.join(base_dir, "myDB.sqlite")
# 支持追踪修改
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] =True
# flask服务器加载数据库
db = SQLAlchemy(app)

3)定义数据表
使用pycharm来定义数据表,默认类名就是表名,但是要注意类名和表名还是有所区别:
类名首字母大写,但表名则是完全的小写字母,创建一个表观察一下吧。

class Person(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(32), unique=True)
password = db.Column(db.String(32))
nickname = db.Column(db.String(32), default="")
age = db.Column(db.Integer, default=18)
gender = db.Column(db.String(16), default="男")
score = db.Column(db.Float, nullable=True)

4) 同步数据库

db.create_all()

5) 整理
如果我们在一个.py文件下即写网页视图,又写数据库,同时又兼具运行的任务,那么这个文件的可读性就会降低,所以通常情况下,我们会创建几个不同的.py文件:
- views.py文件写视图相关代码,
- models.py文件负责数据库代码,
- app.py文件负责创建http实例和数据库,
- main.py文件负责运行
让他们各自负责各自的部分,各司其职,这样可读性会大大提高。

二、数据库基本操作

1. 常规操作

数据库的常规操作无外乎增(add)删(delete)改查四个操作,只是不同的编程语言、不同的数据库软件有不同的语法。flask_sqlalchemy的语法如下:

1) 增

# 增加一条数据
person = Person(
username ="maggie",
    password ="123456",
    nickname ="张三",
    gender ="女",
    score =99
)
db.session.add(person)
db.session.commit()

# 增加多条数据
person1 = Person(
username ="lisi",
    password ="123456",
    nickname ="李四",
    gender ="男",
    score =80
)
person2 = Person(
username ="wangwu",
    password ="123456",
    nickname ="王五",
    gender ="女",
    score =90
)
db.session.add_all([person1, person2])
db.session.commit()

注意:增加数据需要进行提交,增加单个数据和增加多个数据的add方法有细微差别。

2) 查

详情请戳:浅谈flask_sqlalchemy(2) - 让人又爱又恨的数据查询

3) 改

# 修改id为5的用户的性别为男
person = Person.query.get(5)
person.gender = '男'
db.session.commit()

4) 删

# 删除id为50的用户
person = Person.query.get(1)
db.session.delete(person)
db.session.commit()

5) 整理
常规的flask_sqlalchemy操作比较复杂,但是基于面向对象可以进行修改。

  • 所有表默认都有主键id
  • 所有的数据都需要增删改,即都需要提交commite
    所以我们可以将其整理为
class Base(db.Model):
    # 作为父类完成被继承,本身不执行
    __abstract__ = True
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    def save(self):
        db.session.add(self)
        db.session.commit()
    def delete(self):
        db.session.delete(self)
        db.session.commit()
    def update(self):
        db.session.commit()

class Person(Base):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(32), unique=True)
    password = db.Column(db.String(32))
    nickname = db.Column(db.String(32), default="")
    age = db.Column(db.Integer, default=18)
    gender = db.Column(db.String(16), default="男")
    score = db.Column(db.Float, nullable=True)

我们将增删改都整理在Base父类中,新建的表继承父类Base,同时也继承了父类中增加(save方法)、删除(delete方法)、修改(update方法),简化了代码。
例如:

p = Person()
p.username = "hello"
p.password = "world"
p.save()

2. 关系操作

在数据库建模的过程中,不止有基于业务主体描述的数据库模型,还有关系模型,常用的关系模型有以下两种:

(1)一对多关系
  • 例如:员工和职位的关系就是一对多关系,一个员工只能有一个职位,一个职位可以有很多员工。
  • 在数据库中,我们通常采用外键的方式来进行一对多约束
    外键用字段db.ForeignKey("对应主键表的字段")
  • 同时需要一个快速的方法进行两表的查询,所以在主键表中设置反向映射来方便查询。
    反向映射:
字段 = db.relationship(
      "多表的类名", 
      backref = "多表查询一表使用的字段"
)
  • 小总结
    一表是主键表
    多表是外键表
    在外键表里搭外键
    在主键表里搭反向映射
职位表.png
"""
具体代码
"""
class Person(Base):
    """
    职员表
    """
    username = db.Column(db.String(32), unique=True)
    password = db.Column(db.String(32))
    nickname = db.Column(db.String(32), default="")
    age = db.Column(db.Integer, default=18)
    # 声明p_position是一个外键整形字段,对应position表的id
    p_position = db.Column(db.Integer, db.ForeignKey("position.id"))

class Position(Base):
    """
    职位表
    """
    p_name = db.Column(db.String(32))
    p_level = db.Column(db.Integer)
    p_department = db.Column(db.Integer, db.ForeignKey("department.id"))
    # 映射到职员表
    p_person = db.relationship(
        "Person",
        backref="person_position"
    )

# 查询财务部职员职位的员工
person = Position.query.get(7)
for p in person.p_person:
    print(p.nickname, person.p_name)

# 查询id为1的职员的职位
person = Person.query.get(1)
print(person.nickname, person.person_position.p_name)
参考图片1.png
参考图片2.png
(2) 多对多关系
  • 例如:职位和对应的权限,每个职位有对应的多个权限,但每个职位的权限又不太一样
  • 多对多关系的解决依赖于建立中间表
    关系图解.png
# 中间表:中间表一定要这样创建
pos_per = db.Table(
    "pos_per",  # 表名
    db.Column("pos_id", db.Integer, db.ForeignKey("position.id")),
    db.Column("per_id", db.Integer, db.ForeignKey("permission.id")),
)


class Position(Base):
    """
    职位表
    """
    p_name = db.Column(db.String(32))
    p_level = db.Column(db.Integer)
    p_department = db.Column(db.Integer, db.ForeignKey("department.id"))
    # 映射到职员表
    p_person = db.relationship(
        "Person",
        backref="person_position"
    )
    # 映射到权限表
    p_permission = db.relationship(
        "Permission",
        secondary=pos_per,          # 中间表
        backref="p_position"        # 反向映射字段
    )


class Permission(Base):
    """
    权限表
    """
    per_name = db.Column(db.String(256))

# 查询权限对应的职位
permission = Permission.query.get(2)
print(permission.per_name)    # 组织部门会议
for p in permission.p_position:
    print(p.p_name)    # 经理  主任

# 查看职位对应的权限
position = Position.query.get(12)
print(position.p_name)    # 主任
for per in position.p_permission:
    print(per.per_name)    # 查看部门考勤  组织部门会议

三、知识补充库

1. pypinyin模块

pypinyin是一个好用的第三方模块,可以将汉字转换成拼音,在某些时候给我们提供方便

1)下载模块
可以直接在pycharm下的terminal命令行进行安装
安装命令:

pip install pypinyin

2)导入模块

import pypinyin

3)使用

py_name = pypinyin.lazy_pinyin("张三")

如有不妥,欢迎指正

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容