ORM(object relationship model)是我们在开发当中必定会用到的一项数据库操作技术,他是我们脱离了繁琐的原生SQL语句,极大的简化了我们开发的难度,使用flask在开发中我们一般使用sqlalchemy作为ORM。
python中想要使用SQLAlchemy需要安装:pip install SQLAlchemy,但在flask中我们可以使用flask封装的SQLAlchemy:flask-SQLAlchemy,pip install flask-SQLAlchemy
安装完成之后连接mysql数据库:

from fask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()
app = Flask(__name__)
db = SQLAlchemy(app)
# 配置数据库路径 mysql://user:password@host:port/database
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:123@localhost:9508/flask_test"
#必须设置成 True (默认为None),Flask-SQLAlchemy 将会追踪对象的修改并且发送信号。这需要额外的内存。
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
# 还有一些其他的配置项,可阅读:http://www.pythondoc.com/flask-sqlalchemy/config.html

现在我们就可以继承db.Model来创建数据表了:

class BaseModel(db.Model):
    __abstract__ = True # 抽象类,可以将其他数据表中的公共字段存放在这个类中,然后继承该类
    id =db.Column(db.Integer,primary_key=True,autoincrement=True)

Article_Tag =db.Table(
    "acticle_tag",
    db.Column("id",db.Integer,primary_key=True,autoincrement=True),
    db.Column("article_id",db.Integer,db.ForeignKey("article.id")),
    db.Column("tag_id",db.Integer,db.ForeignKey("tag.id"))
) # 创建多对多表

class Article(BaseModel):
    __tablename__ = "article"
    title = db.Column(db.String(20))
    author_id = db.Column(db.Integer,db.ForeignKey("user.id"))
    tag = db.relationship(
        "Tag", # 定义关联的数据表,正向查询时使用“tag”进行查询
        secondary=Article_Tag, # 多对多关系中关联的中间表
        lazy="dynamic", # 指定sqlalchemy数据库何时加载数据
        backref=db.backref("article",lazy="dynamic") # 指定反向查询时使用的名称和何时加载数据
    )

class Tag(BaseModel):
    __tablename__ = "tag"
    name = db.Column(db.String(20))

class User(BaseModel):
    __tablename__ = "user"
    username = db.Column(db.String(10))
    phone = db.Column(db.String(11))
    article = db.relationship(
        "Article",
        backref = "Author"
    )

db.create_all() # 在数据库中生成数据表
#db.drop_all() 删除数据库中的数据表

想要更改数据表时只能使用drop_all()和create_all(),在实际工作中是非常的不方便的,想要和django中的ORM一样实现数据库迁移需要使用到flask-script和flask-migrate两个包,具体操作可参考:。
SQLAlchemy中Column常用参数:
default:默认值
nullable:是否为空
primary_key:主键
unique:是否唯一
autoincrement:是否自增
onupdate:更新时执行
name:数据库映射后的属性
SQLAlchemy常用数据类型:
Integer:整形,映射到数据库中是int类型。
Float:浮点类型,映射到数据库中是float类型。他占据的32位。
Double:双精度浮点类型,映射到数据库中是double类型,占据64位。
String:可变字符类型,映射到数据库中是varchar类型.
Boolean:布尔类型,映射到数据库中的是tinyint类型。
DECIMAL:定点类型。是专门为了解决浮点类型精度丢失的问题的。在存储钱相关的字段的时候建议大家都使用这个数据类型。并且这个类型使用的时候需要传递两个参数,第一个参数是用来标记这个字段总能能存储多少个数字,第二个参数表示小数点后有多少位。
Enum:枚举类型。指定某个字段只能是枚举中指定的几个值,不能为其他值。在ORM模型中,使用Enum来作为枚举
Date:存储时间,只能存储年月日。映射到数据库中是date类型。在Python代码中,可以使用datetime.date来指定
DateTime:存储时间,可以存储年月日时分秒毫秒等。映射到数据库中也是datetime类型。在Python代码中,可以使用datetime.datetime来指定。示例代码如下:
Time:存储时间,可以存储时分秒。映射到数据库中也是time类型。在Python代码中,可以使用datetime.time来至此那个。
Text:存储长字符串。一般可以存储6W多个字符。如果超出了这个范围,可以使用LONGTEXT类型。映射到数据库中就是text类型。
LONGTEXT:长文本类型,映射到数据库中是longtext类型。
在一对一、一对多或者多对多关系中我们可以定义db.relationship()使关联查询时更加方便,relationship中常用参数:
backref:在关系的另一个模型中添加的反向引用,即反向查询时使用的名称。
primaryjoin:明确指定两个模型之间使用的联结条件,只在模棱两可的关系中需要指定。
foreign_keys:接收一个列表,大多数情况下, db.relationship() 都能自行找到关系中的外键, 但有时却无法决定把哪一列作为外键,此时可以使用foreign_keys来明确指定哪一个作为外键。
lazy:指定如何加载相关数据,可选值:

  • select(首次访问时按需加载)
  • immediate(源对象加载后就加载)
  • joined(加载数据,但使用联结)
  • subquery(立即加载,但使用子查询)
  • noload(永不加载)
  • dynamic(不加载数据,但提供加载数据的查询)

uselist:如果设为False,不适用列表,而使用标量值。
order_by:指定关系中数据的排序方式。
secondary:指定多对多关系中关系表的名字。
secondaryjoin:SQLAlchemy无法自行决定时,指定多对多关系中的二级联结条件。