zoukankan      html  css  js  c++  java
  • flask--relationship

    本文主要介绍如何使用flask操作数据库。

    数据库按照一定规则保存程序数据,程序再发起查询取回所需的数据。Web程序最常用基于关系模型的数据库,这种数据库也称为SQL数据,因为它们使用结构化查询语句。不过最近几年文档数据库和键值对数据库成了流行的替代选择,这两种数据库合称为NoSQL数据库。

    大多数的数据库引擎都有对应的Python包,包括开源宝和商业包。Flask并不限制你使用何种类型的数据库包,因此可以根据自己的喜好选择使用MySQL、Postgres、SQLite,Redis、MongoDB或者CouchDB。

    如果这些都无法满足需求,还有一些数据库抽象层代码包供选择,例如SQLAlchemy和MongoEngine。你可以使用这些抽象包直接处理高等级的Python对象,而不用处理如表、文档或查询语言此类的数据库实体。

    选择框架时,你不一定非得选择已经集成了Flask的框架,但选择这些框架可以节约你编写集成代码的时间。使用集成了Flask的框架可以简化配置和操作,所以专门为Flask开发的扩展是你的首选。

    关于选择使用的数据库框架,选择的是Flask-SQLAlchemy。

    0.安装Flask-SQLAlchemy

    pip install flask-sqlalchemy
    

    1.配置Flask-SQLAlchemy

    在Flask-SQLAlchemy中,数据库使用URL指定。

    MySQL : mysql://username:password@hostname/database
    Postgres : postgresql://username:password@hostname/database
    SQLite : sqlite:////absolute/path/to/database

    在这些URL中,hostname表示MySQL服务所在的主机,可以是本地主机(localhost),也可以是远程服务器。数据库服务器上可以托管多个数据库,因此database表示要使用的数据库名。如果数据库需要进行认证,username和password表示数据库的用户名和密码。

    SQLite数据库不需要使用服务器,因此不用指定hostname、username和password。URL中的database是硬盘上文件的文件名。

    程序使用的数据库URL必须保存到Flask配置对象的SQLALCHEMY_DATABASE_URI键中。配置对象中还有一个很有用的选项,即SQLALCHEMY_ON_REARDOWN键,将其设置为True时,每次请求结束后都会自动提交数据库中的变动。

    我们使用SQLite数据库,配置代码 如下:

    1.  
      from flask import Flask
    2.  
      from flask.ext.sqlalchemy import SQLAlchemy
    3.  
      import os
    4.  
       
    5.  
      baseDir = os.path.abspath(os.path.dirname(__file__))
    6.  
       
    7.  
      app = Flask(__name__)
    8.  
      app.config['SQLALCHEMY_DATABASE_URI'] =
    9.  
      'sqlite:////' + os.path.join(baseDir,'data.sqlite')
    10.  
      app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
    11.  
       
    12.  
      db = SQLAlchemy(app)
    13.  
       

    2.定义模型

    定义一个用户表users和一个角色表roles,代码如下:

    1.  
      class User(db.Model):
    2.  
      __tablename__ = 'users'
    3.  
      id = db.Column(db.Integer,primary_key=True)
    4.  
      username = db.Column(db.String(64),unique=True,index=True)
    5.  
       
    6.  
      def __repr__(self):
    7.  
      return '<User %r>' % self.username
    8.  
       
    9.  
       
    10.  
      class Role(db.Model):
    11.  
      __tablename__ = 'roles'
    12.  
      id = db.Column(db.Integer,primary_key=True)
    13.  
      name = db.Column(db.String(64),unique=True)
    14.  
       
    15.  
      def __repr__(self):
    16.  
      return '<Role %r>' % self.name
    17.  
       

    解释下:

    0.两个类User和Role继承自db.Model
    1.__tablename__用来指定表名称
    2.db.Column函数指定了数据库中字段的类型,是否是主键(primary_key),是否唯一(unique),是否加索引(index),还有其他的比如:是否可以为空(nullable=True),默认值(default)

    3.关系

    使用关系型数据库,不指定关系怎么能行。定义模型中我们没有指定关系,一个用户有一个角色,一个角色可以属于多个用户,典型的一对多的关系,如何在Flask-SQLAlchemy中定义关系?

    上代码:

    1.  
      class User(db.Model):
    2.  
      __tablename__ = 'users'
    3.  
      id = db.Column(db.Integer,primary_key=True)
    4.  
      username = db.Column(db.String(64),unique=True,index=True)
    5.  
       
    6.  
      role_id = db.Column(db.Integer,db.ForeignKey('roles.id'))
    7.  
       
    8.  
      def __repr__(self):
    9.  
      return '<User %r>' % self.username
    10.  
       
    11.  
       
    12.  
      class Role(db.Model):
    13.  
      __tablename__ = 'roles'
    14.  
      id = db.Column(db.Integer,primary_key=True)
    15.  
      name = db.Column(db.String(64),unique=True)
    16.  
       
    17.  
      users = db.relationship('User',backref='role')
    18.  
       
    19.  
       
    20.  
      def __repr__(self):
    21.  
      return '<Role %r>' % self.name
    22.  
       

    添加了两行代码:

    第一行,User类中:

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

    这句话比较好理解,和上面普通变量差不多,就是User类中添加了一个role_id变量,数据类型db.Integer,第二个参数指定外键是哪个表中哪个id。

    第二行,Role类中:

     users = db.Relationship('User',backref='role')
    

    这句话比较复杂,仔细读下面的话:

    0.添加到Role模型中的users属性代表这个关系的面向对象视角。对于一个Role类的实例,其users属性将返回与角色相关联的用户组成的列表。
    1.db.Relationship()第一个参数表明这个关系的另一端是哪个模型(类)。如果模型类尚未定义,可使用字符串形式指定。
    2.db.Relationship()第二个参数backref,将向User类中添加一个role属性,从而定义反向关系。这一属性可替代role_id访问Role模型,此时获取的是模型对象,而不是外键的值。

    上面的关系为一对多关系的表示,一对一怎么办?
    调用db.Relationship()时需要把userlist参数设置为False。如下:

    1.  
      db.Relationship('User',backref='role',uselist=False)
    2.  
       

    至于多对多关系,以后会慢慢介绍。

    4.数据库操作

    数据库操作,基本的一些:数据库、表创建或删除,数据的增删改查。

    0.创建数据库和表

    1.  
      db.create_all()
    2.  
       

    上面说的users表和roles表就创建了。

    1.删除数据库

    1.  
      db.drop_all()
    2.  
       

    1.插入行

    1.  
      role_admin = Role(name='Admin')
    2.  
      user_tom = User(username='tom',role=role_admin)
    3.  
      user_jim = User(username='jim',role=role_admin)
    4.  
      user_tim = User(username='tim',role=role_admin)
    5.  
      user_sam = User(username='sam',role=role_admin)
    6.  
      db.session.add(role_admin)
    7.  
      db.session.add(user_tom)
    8.  
      db.session.add(user_jim)
    9.  
      db.session.commit()

    通过数据库会话管理对数据库所做的改动,在Flask-SQLAlchemy中,会话由db.session表示,准备把队形写入数据库之前,先要将其添加到会话中。写入数据库需要调用db.session.commit()方法。

    2.修改行

    我们将role_admin变量中name为Admin改成Administrator。

    1.  
      role_admin.name='Administrator'
    2.  
      db.session.add(role_admin)
    3.  
      db.session.commit()

    3.删除行

    删除Jim用户

    1.  
      db.session.delete(user_jim)
    2.  
      db.session.commit()
    3.  
       

    4.查询行

    查询所有用户

    User.query.all() #返回结果:[<User 'tom'>, <User 'tim'>, <User 'sam'>]
  • 相关阅读:
    vue中的ref,refs使用
    setTimeout 为0的作用
    click 和 mousedown 以及map地图的pointerdown
    electron图标
    websocket
    居中
    一键生成vue模板
    IntelliJ IDEA 安装破解及汉化详解
    基础的一些东西
    git 合作开发
  • 原文地址:https://www.cnblogs.com/ithairy/p/9769510.html
Copyright © 2011-2022 走看看