美文网首页
Flask-SQLalchemy

Flask-SQLalchemy

作者: 猴子精h | 来源:发表于2017-08-17 19:16 被阅读363次

    定义

    from flask_sqlalchemy import SQLAlchemy
    
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
    db = SQLAlchemy(app)
    

    or

    from flask_sqlalchemy import SQLAlchemy  
    
    app = Flask(__name__)
    db = SQLAlchemy()  
    db.init_app(app)  
    config[config_name].init_app(app) # config.py里,指定了数据库文件,比如 mysql:///, sqlite:///  
    

    关系

    一对多(one-to-many)

    关系使用relationship()函数表示。然而外键必须用类sqlalchemy.schema.ForeignKey单独声明:

    class Person(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(50))
        addresses = db.relationship('Address', backref='person',
                                    lazy='dynamic')
    
    class Address(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        email = db.Column(db.String(50))
        person_id = db.Column(db.Integer, db.ForeignKey('person.id'))
    

    一对一

    只需要添加uselist=False属性

    class Person(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(50))
        addresses = db.relationship('Address', backref='person',
                                    lazy='dynamic', uselist=False)
    
    class Address(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        email = db.Column(db.String(50))
        person_id = db.Column(db.Integer, db.ForeignKey('person.id'))
    

    多对多关系(many-to-many)

    如果您想要用多对多关系,您需要定义一个用于关系的辅助表。对于这个辅助表, 强烈建议不使用模型,而是采用一个实际的表:

    tags = db.Table('tags',
        db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
        db.Column('page_id', db.Integer, db.ForeignKey('page.id'))
    )
    
    class Page(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        tags = db.relationship('Tag', secondary=tags,
            backref=db.backref('pages', lazy='dynamic'))
    
    class Tag(db.Model):
        id = db.Column(db.Integer, primary_key=True)
    

    多对多关系使用(在使用多对多关系时需要先将相对应的对象查询出来):

    • 添加关系
    page_1 = Page()
    tag_1 = Tag()
    db.session.add(page_1)
    db.session.add(tag_1)
    db.session.commit()
    
    # 添加对应关系
    page_1.tags.append(tag_1)
    db.session.add(page_1)
    db.session.commit()
    
    • 删除关系
    page_1.tags.remove(tag_1)
    db.session.add(page_1)
    db.session.commit()
    
    • 查询
    # 列出所有的tags数组
    page_1.tags.all()
    

    操作

    models.py 定义如下:

    class Role(db.Model):
        __tablename__ = 'roles'
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(64), unique=True)
        users = db.relationship('User', backref='role', lazy="dynamic")
    
        def __init__(self, name):
            self.name = name
    
        def __repr__(self):
            return '<Role %r>' % self.name
    
    
    class User(db.Model):
        __tablename__ = 'users'
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(64), unique=True, index=True)
        role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    
        def __init__(self, username, role):
            self.username = username
            self.role = role
    
        def __repr__(self):
            return '<User %r>' % self.username
    

    创建 删除表

    db.create_all()
    db.drop_all()
    

    插入行

    admin_role = Role(name='Admin')
    db.session.add(admin_role)
    db.session.commit()
    

    修改行

    admin_role.name = 'Administartor'
    db.session.add(admin_role)
    db.session.commit()
    

    删除行

    db.session.delete(admin_role)
    db.session.commit()
    

    查询行

    Flask-SQLAlchemy为每个模型类都提供了query对象。

    Role.query.all()
    User.query.filter_by(role=user_role).all()
    

    常用的SQLAlchemy查询过滤器

    方法 说明
    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 对象,它包含指定范围内的结果

    常用的SQLAlchemy查询执行函数

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

    Flask 数据库迁移工具 flask-migrate

    仅当数据库表不存在时,Flask-SQLAlchemy 才会根据模型进行创建。因此,更新表的唯一方式就是先删除旧表,不过这样做会丢失数据库中的所有数据

    manage.py添加db命令

    from flask_migrate import Migrate, MigrateCommand
    
    migrate = Migrate(app, db)
    manager.add_command("db", MigrateCommand)
    

    第一次使用:

    • 初始化:python manage.py db init这个命令会在项目下创建 migrations 文件夹,所有迁移脚本都存放其中。
    • 创建第一个版本:python manage.py db migrate -m "initial migration" 检查migrations/versions,检查里面表格及字段
    • 运行升级 python manage.py db upgrade,会把项目使用的数据库文件,更新为新的表格、字段,同时保留数据

    更新:

    • 更新表格的字段
    • 再次运行一下 db migrate -m 'xx' -> 相当于commit 更新到/migrate目录
    • db upgrade -> 数据库会更新

    相关文章

      网友评论

          本文标题:Flask-SQLalchemy

          本文链接:https://www.haomeiwen.com/subject/zjmnrxtx.html