首页 > 数据库技术 > 详细

Python---Flask--03--SQLAlchemy

时间:2019-06-21 19:51:16      阅读:106      评论:0      收藏:0      [点我收藏+]

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

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

使用Flask-SQLAlchemy管理数据库

安装

pip install flask-sqlalchemy

基本使用

FLask-SQLAlchemy数据库URL
|数据库引擎|URL|
|---|---|
|MySQL| mysql://username:password@hostname/database|
|Postgres | postgresql://username:password@hostname/database|
|SQLite(Unix)| sqlite:////absolute/path/to/database|
|SQLite(Windows)| sqlite:///c:/absolute/path/to/database|

配置

from flask.ext.sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
db = SQLAlchemy(app)

db 对象是 SQLAlchemy 类的实例,表示程序使用的数据库,同时还获得了 Flask-SQLAlchemy提供的所有功能。

定义模型

from app import db
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin


class User(db.Model, UserMixin):
    __tablename = 'user'  #表名称

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True)
    email = db.Column(db.String(100), unique=True)
    password = db.Column(db.String(100))
    add_time = db.Column(db.DateTime, default=datetime.now)
    state = db.Column(db.Integer, default=1, comment='状态 1--有效 0--无效')

    def __repr__(self):
        return '<User %r>'% self.username
    # @property
    # def password(self):
    #     raise AttributeError('password not read')
    #
    # @password.setter
    # def password(self,password):
    #     self.password = generate_password_hash(password)


    def verify_password(self,pwd):
        """验证密码是否正确"""
        return check_password_hash(self.password, pwd)

类变量 tablename 定义在数据库中使用的表名。如果没有定义 tablename,Flask-SQLAlchemy 会使用一个默认名字,但默认的表名没有遵守使用复数形式进行命名的约定,所以最好由我们自己来指定表名。其余的类变量都是该模型的属性,被定义为 db.Column类的实例。
db.Column 类构造函数的第一个参数是数据库列和模型属性的类型。列出了一些可用的列类型以及在模型中使用的 Python 类型。
|类型|Python中的类型|说明|
|---|---|---|
|Integer|Int|整形|
|SmallInteger|int|短整型|
|BigInteger|ing或者long|不限长度|
|Float|float|浮点型|
|Numeric|decimal|定点数|
|String|str|字符串|
|Text|str|文本|
|DateTime|datetime.datetime|日期和时间|
|Date|datetime.date|日期|
|Time|datetime.time|时间|
|Boolean|bool|布尔|
|Enum|str|枚举|
|Interval|datetime.timedelta|时间间隔|

db.Column中其余参数指定属性的配置选项:
|选项名|说明 |
|---|---|
|primary_key|如果设置为True,则是主键|
|unique|如果设置为True,这列不允许出现重复|
|index| 如果设置为True,为这列创建索引,提示查询效率|
|nullable| 如果设置为True, 这列允许使用空值,如果设为Fasle,这列不允许使用空值
|default|为这列设置默认值|

关系

关系型数据库使用关系把不同表中的行联系起来。表示用户和角色之间的一种简单关系。这是角色到用户的一对多关系,因为一个角色可属于多个用户,而每个用户都只能有一个角色。
一对多关系在模型类中的表示方法如示例所示:

class Role(db.Model):
 # ...
    users = db.relationship('User', backref='role')

class User(db.Model):
 # ...
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

关系使用 users 表中的外键连接了两行。添加到 User 模型中的 role_id 列被定义为外键,就是这个外键建立起了关系。传给 db.ForeignKey() 的参数 ‘roles.id‘ 表明,这列的值是 roles 表中行的 id 值。

添加到 Role 模型中的 users 属性代表这个关系的面向对象视角。对于一个 Role 类的实例, users 属性将返回与角色相关联的用户组成的列表。db.relationship() 的第一个参数表明这个关系的另一端是哪个模型。如果模型类尚未定义,可使用字符串形式指定。

db.relationship() 中的 backref 参数向 User 模型中添加一个 role 属性,从而定义反向关系。这一属性可替代 role_id 访问 Role 模型,此时获取的是模型对象,而不是外键的值。

大多数情况下,db.relationship() 都能自行找到关系中的外键,但有时却无法决定把哪一列作为外键。例如,如果 User 模型中有两个或以上的列定义为 Role 模型的外键,SQLAlchemy 就不知道该使用哪列。如果无法决定外键,你就要为 db.relationship() 提供额外参数,从而确定所用外键。表 列出了定义关系时常用的配置选项。
表 常用的SQLAlchemy关系选项
|选项名| 说  明|
|---|---|
|backref| 在关系的另一个模型中添加反向引用|
|primaryjoin| 明确指定两个模型之间使用的联结条件。只在模棱两可的关系中需要指定|
|lazy |指定如何加载相关记录。可选值有 select(首次访问时按需加载)、immediate(源对象加
载后就加载)、joined(加载记录,但使用联结)、subquery(立即加载,但使用子查询),
noload(永不加载)和 dynamic(不加载记录,但提供加载记录的查询)|
|uselist |如果设为 Fales,不使用列表,而使用标量值|
|order_by |指定关系中记录的排序方式|
|secondary| 指定多对多关系中关系表的名字|
|secondaryjoin| SQLAlchemy 无法自行决定时,指定多对多关系中的二级联结条件|

除了一对多之外,还有几种其他的关系类型。一对一关系可以用前面介绍的一对多关系表示,但调用 db.relationship() 时要把 uselist 设为 False,把“多”变成“一”。多对一关系也可使用一对多表示,对调两个表即可,或者把外键和 db.relationship() 都放在“多”这一侧。最复杂的关系类型是多对多,需要用到第三张表,这个表称为关系表。

数据库操作

添加

import db
user = User(username='',password='')
db.session.add(iser)
dn.session.commit()

更新

import db
user = User.query.get(id)
user.name='aaaaaaa'
db.session.commit()

删除

import db
user.User.query.get(id)
db.session.delete(user)
db.session.commit()

查询

query.all() 获取全部
query.filter() 把过滤器添加到原查询上,返回一个新的查询
filter_by() 把等值过滤器添加到原查询上,返回一个新的查询
limit() 使用指定的值限制返回的结果数量,返回一个新的查询
offset() 偏移原查询返回的结果,返回一个新的结果
order_by 根据指定条件对原查询结果进行排序,返回一个新查询
group_by 根据指定条件对原查询结果进行分组,返回一个新的查询
first() 返回查询的第一个结果,如果没有返回None
first_or_404() 返回查询的第一个结果,如果没有结果返回404错误
get() 返回指定主键对应的行,如果没有返回None
get_or_404() 返回指定主键对应的行,如果没有找到对象,则终止请求,返回404错误
count() 返回查询结果的数量
paginate() 返回一个Paginage对象,它包含指定范围的结果

在视图函数中操作数据库

@home.route('/register', methods=['GET', 'POST'])
def register():
    """注册"""
    form = RegisterForm()

    if form.validate_on_submit():
        data = form.data

        user = User(
            username=data['username'],
            password=generate_password_hash(data['password']),
            email=data['email']
        )
        db.session.add(user)
        db.session.commit()
        flash('注册成功')
        return redirect(url_for('home.login'))

    return render_template('/home/user/register.html', form=form)

Python---Flask--03--SQLAlchemy

原文:https://www.cnblogs.com/sunshenggang/p/11066099.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!