python小记-flask-sqlalchemy

创建

安装

pip install flask-sqlalchemy

初始化

from flask_sqlalchemy import SQLAlchemy

from flask import Flask

app = Flask(__name__)

db = SQLAlchemy(app)

连接数据库

示例:

app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://root:123.com@localhost/test01"

定义数据库模型

# 模型要继承于db.Model基类
class User(db.Model):
    # 指定表名,不设置默认 User -> user
    __tablename__ = "users"
    # 字段由db.Column的实例表示,类型通过构造方法的第一个参数传入,第二个参数实例化字段时的一些参数字段
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True)
    
    def __repr__(self):
        """非必须, 用于在调试或测试时, 返回一个具有可读性的字符串表示模型."""
        return '<Role %r>' % self.name

第一个数据类型 

第二个参数字段说明

 创建数据库和表

# 丢弃表    
db.drop_all()
# 创建表
db.create_all()

CURD

Create

示例是在python shell中进行

# 导入模型类和数据库
from test import User,db
# 实例化模型类
user01 = User(username="lilei")
user02 = User(username="zhangsan")
user03 = User(username="wangwu")
# 添加记录到数据库会话中
db.session.add(user01)
db.session.add(user02)
db.session.add(user03)
# 提交保存
db.session.commit()

Read

查询规则:

<模型类>.query.<过滤方法>.<查询方法>

示例:

# 查询
# 查询user表中所有记录
User.query.all()
# 返回查询的第一条记录,如果没有返回None
User.query.first()
# 返回指定的主键ID的值
User.query.get(id)
# 查看表中有多少条数据
User.query.count()

# 过滤
# 查找名字为lisi的记录
User.query.filter_by(username='lisi').first()
# like用法
User.query.filter(User.username.like('%is%')).first()
# in 用法
User.query.filter(User.username.in_(['lisi','zhangsan'])).all()
# notin 用法
User.query.filter(~User.username.in_(['lisi','zhangsan'])).all()
# and 和 or 用法
# 多条件可以直接用逗号拼接
User.query.filter(User.username=='lisi',User.id==3).all()
# 引入and和or
from sqlalchemy import and_, or_
# 使用 and
User.query.filter(and_(User.username=='lisi',User.id==3)).all()
# 使用 or
User.query.filter(or_(User.username=='lisi',User.id==2)).all()

更多查询和过滤方法: 

 

Update

示例:

# 查询出要修改的对象
user01 = User.query.get(2)
# 修改值
user01.username="sunliu"
# 提交更新
db.session.commit()

Delete

# 查询出要删除的对象
user01 = User.query.get(2)
# 删除操作
db.session.delete(user01)
# 提交修改
db.session.commit()

关系

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
from sqlalchemy import and_, or_

app = Flask(__name__)

# 连接数据库
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql://root:123.com@localhost/test01"
# 配置语句追踪
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
pymysql.install_as_MySQLdb()
db = SQLAlchemy(app)


# class Role(db.Model):
#     __tablename__ = "roles"
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(64), unique=True)
#
#     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)
#
#     def __repr__(self):
#         """非必须, 用于在调试或测试时, 返回一个具有可读性的字符串表示模型."""
#         return '<Role %r>' % self.username

# 单向关系
# class Author(db.Model):
#     __tablename__ = "author"
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(64), unique=True)
#     phone = db.Column(db.String(20))
#     # 定义关系属性,relationship的参数为另一侧的模型名称
#     # 当被调用时,会找到关联的另一侧表的外键,然后反向查询article表中所有author_id为当前记录的,并返回此记录的列表
#     article = db.relationship("Article")
#
#     def __repr__(self):
#         """非必须, 用于在调试或测试时, 返回一个具有可读性的字符串表示模型."""
#         return '<Author %r>' % self.name
#
#
# class Article(db.Model):
#     __tablename__ = "article"
#     id = db.Column(db.Integer, primary_key=True)
#     title = db.Column(db.String(64), unique=True)
#     body = db.Column(db.Text)
#     author_id = db.Column(db.Integer, db.ForeignKey("author.id"))
#
#     def __repr__(self):
#         """非必须, 用于在调试或测试时, 返回一个具有可读性的字符串表示模型."""
#         return '<Article %r>' % self.title

#
# # 双向关系
# class Writer(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     name = db.Column(db.String(64), unique=True)
#     # 定义关系属性,relationship的参数为另一侧的模型名称
#     # 当被调用时,会找到关联的另一侧表的外键,然后反向查询article表中所有author_id为当前记录的,并返回此记录的列表
#     books = db.relationship("Book", back_populates='writer')
#
#
# class Book(db.Model):
#     id = db.Column(db.Integer, primary_key=True)
#     title = db.Column(db.String(64), unique=True)
#     writer_id = db.Column(db.Integer, db.ForeignKey('writer.id'))
#     # 定义关系属性,relationship的参数为另一侧的模型名称
#     # 当被调用时,会找到关联的另一侧表的外键,并返回此记录的列表
#     writer = db.relationship("Writer", back_populates='books')

# 一对一
class Country(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    # 定义关系属性,relationship的参数为另一侧的模型名称
    # 创建另一侧的关系属性,将集合属性userlist设为False
    capital = db.relationship("Capital", userlist=False)


class Capital(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    country_id = db.Column(db.Integer, db.ForeignKey('country.id'))
    # 定义关系属性,relationship的参数为另一侧的模型名称
    # 当被调用时,会找到关联的另一侧表的外键,并返回此记录的列表
    writer = db.relationship("Country")


if __name__ == '__main__':

    # 创建删除表
    # db.drop_all()
    # db.create_all()
    # 单向关系 示例
    # foo = Author(name="foo")
    # spam = Article(title='span')
    # ham = Article(title='ham')
    # db.session.add(foo)
    # db.session.add(spam)
    # db.session.add(ham)
    # 配置属性关系
    # 指定author_id
    # spam = Article.query.get(1)
    # spam.author_id = 1
    # 通过关系属性操作,推荐使用
    # ham = Article.query.get(2)
    # foo = Author.query.get(1)
    # 如果要解除关系属性可以使用remove
    # foo.article.append(ham)
    # db.session.commit()
    # print(foo.article)

    # 双向关系示例
    # 写入记录
    # king = Writer(name='king')
    # carrie = Book(title="carrie")
    # it = Book(title="it")
    # db.session.add(king)
    # db.session.add(carrie)
    # db.session.add(it)
    # 查询出记录
    # carrie = Book.query.get(1)
    # it = Book.query.get(2)
    # king = Writer.query.get(1)
    # 建立关系
    # carrie.writer = king
    # it.writer = king
    # 解除关系
    # carrie.writer = None
    # 展示结果
    # print(king.books)
    # # 提交更新
    # db.session.commit()


问题一

启动时,报错:Error loading MySQLdb module: No module named 'MySQLdb'。

MySQLdb并不支持Python3.5,因此只能找别的类库代替。

使用pymysql代替MySQLdb,因为两者的用法完全一致,步骤:

1. PIP install pymysql

2. 执行成功后,打开__init__.py,添加如下:

import pymysql
pymysql.install_as_MySQLdb()

问题二

 启动时,出现警告FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True or False to suppress this warning.
  'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '

flask-sqlalchemy建议设置SQLALCHEMY_TRACK_MODIFICATIONS,此配置决定是否追踪对象的修改,默认None,设置为False

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

 终极版:

# 一对多关系

class Role(db.Model):
    # ...
    # db.relationship() 的第一个参数表明这个关系的另一端是哪个模型
    #  backref 参数向 User 模型中添加一个 role 属性,从而定义反向关系。这一属性可替代 role_id 访问 Role 模型,此时获取的是模型对象,而不是外键的值
    users = db.relationship('User', backref='role')

class User(db.Model):
    # ...
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
选项名说 明
backref在关系的另一个模型中添加反向引用
primaryjoin明确指定两个模型之间使用的联结条件。只在模棱两可的关系中需要指定
lazy指定如何加载相关记录。可选值有 select (首次访问时按需加载)、immediate (源对象加载后就加载)、 joined (加载记录,但使用联结)、 subquery (立即加载,但使用子查询),noload (永不加载)和 dynamic (不加载记录,但提供加载记录的查询)
uselist如果设为 Fales ,不使用列表,而使用标量值
order_by 指定关系中记录的排序方式
secondary 指定多对多关系中关系表的名字
secondaryjoinSQLAlchemy 无法自行决定时,指定多对多关系中的二级联结条件
# 多对多
# 建立关联表存储关系
tmp_tab = db.Table('tmp_tab',
                   db.Column('student_id', db.Integer, db.ForeignKey('student.id')),
                   db.Column('class_id', db.Integer, db.ForeignKey('class.id')))



class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))
    # 原始表添加关联表, 仍然使用relationshi定义关系,
    classes = db.relationship('Class',
                              # 指定关联表
                              secondary=tmp_tab,
                              # 隐式定义引用关系
                              backref=db.backref('students', lazy='dynamic'),
                              lazy='dynamic')
    # 


class Class(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值