python小记-flask-sqlalchemy

创建

安装

pip install flask-sqlalchemy

初始化

from flask_sqlalchemy import SQLAlchemy

from flask import Flask

app = Flask(__name__)

db = SQLAlchemy(app)

连接数据库

python小记-flask-sqlalchemy_第1张图片

示例:

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 '' % self.name

第一个数据类型 

python小记-flask-sqlalchemy_第2张图片

第二个参数字段说明

python小记-flask-sqlalchemy_第3张图片

 创建数据库和表

# 丢弃表    
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()

更多查询和过滤方法: 

python小记-flask-sqlalchemy_第4张图片 python小记-flask-sqlalchemy_第5张图片

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 '' % 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 '' % 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 '' % 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 '
' % 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  指定多对多关系中关系表的名字
secondaryjoin SQLAlchemy 无法自行决定时,指定多对多关系中的二级联结条件
# 多对多
# 建立关联表存储关系
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))

你可能感兴趣的:(python,flask,python,后端)