Flask之Sqlalchemy

Sqlalchemy

开发文档:https://www.jianshu.com/p/0ad18fdd7eed

创建数据库

安装

pip instal flask-sqlalchemy

两种配置方法

# 两种配置数据库方法
第一种app.config

from flask import Flask
import pymysql
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 数据库链接的配置,此项必须,格式为(数据库+驱动://用户名:密码@数据库主机地址:端口/数据库名称)
# app.config['SQLALCHEMY_DATABASE_URI']='mysql+pymysql://root:123@127.0.0.1:3306/test'
# app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///'+'数据库存放位置'
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.db')
# 跟踪对象的修改,在本例中用不到调高运行效率,所以设置为False
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=Flask 
app.secret_key='ssssseweweq'
db=SQLAlchemy(app)
第二种 写在配置文件config中
import pymysql

class Config(object):
    # 数据库链接的配置,此项必须,格式为(数据库+驱动://用户名:密码@数据库主机地址:端口/数据库名称)
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root123456@49.233.175.110:3306/db'
    SQLALCHEMY_TRACK_MODIFICATIONS = True  # 跟踪对象的修改,在本例中用不到调高运行效率,所以设置为False
    SCHEDULER_API_ENABLED = True
设置ext配置文件
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
在创建models时导入
from HandlingProject.ext import db # 导入HandlingProject.ext文件下的db实例
class Userinfo(db.Model):  # 继承SQLAlchemy.Model对象,一个对象代表了一张表

创建

create database sqlalchemy; # 创建数据库

 models

class Userinfo(db.Model):  # 继承SQLAlchemy.Model对象,一个对象代表了一张表

    id= db.Column(db.Integer, primary_key=True, autoincrement=True, unique=True)  # id 整型,主键,自增,唯一
    username = db.Column(db.String(20))  # 名字 字符串长度为20
    password = db.Column(db.String(20))  # 年龄 整型,默认为20

    __tablename__ = 'userinfo'  # 该参数可选,不设置会默认的设置表名,如果设置会覆盖默认的表名

    def __init__(self, username, password):  # 初始化方法,可以对对象进行创建
        self.username = username
        self.password = password

db.create_all() # 运行models,连接数据库

常用列选项

# db.Column 中其余的参数指定属性的配置选项
primary_key   # 如果设为 True,这列就是表的主键
autoincrement # 如果设为 True,这列就是表的自增
unique        # 如果设为 True,这列不允许出现重复的值
index         # 如果设为 True,为这列创建索引,提升查询效率
nullable      # 如果设为 True,这列允许使用空值;如果设为 False,这列不允许使用空值
default       # 为这列定义默认值

字段选项

类型python中类型说明
Integer int 普通整数,一般是32位
SmallInteger int 取值范围小的整数,一般是16位
BigInteger int/long 不限制精度的整数
Float float 浮点数
Numeric decimal.Decimal 普通整数,一般是32位
String str 变长字符串,一般String(10)注明长度
Text str 变长字符串,对较长或不限长度的字符串做了优化,不用指明长度
Unicode unicode 变长Unicode字符串
UnicodeText unicode 变长Unicode字符串,对较长或不限长度的字符串做了优化
Boolean boolean 布尔值
Date datetime.date 时间
Time time 时间和日期
LagreBinary str 二进制文件


关系选项

选项说明
backref 在关系的另一模型中添加反向引用
primaryjoin 明确指定两个模型之间使用的联结条件
uselist 如果为False,不使用列表,而使用标量值
order_by 指定关系中记录的排序方式
secondary 指定多对多中记录的排序方式
secondaryjoin 在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结条件

session会话

数据库操作的核心是新建一个会话session,或者叫做事务。在这之后,所有关于数据库的增删改查都要通过这个会话进行操作

session = Session()   # 实例化了一个会话(或叫事务),之后的所有操作都是基于这个对象的
事务对象,session必然有以下这些方法
session.commit()      # 提交会话(事务) 
session.rollback()    # 回滚会话 
session.close()       # 关闭会话

关于数据库中数据的对象在session中的四种状态

session = Session()    #创建session对象
frank = Students(name='Frank')    #数据对象得到创建,此时为Transient状态
session.add(frank)    #数据对象被关联到session上,此时为Pending状态
session.commit()    #数据对象被推到数据库中,此时为Persistent状态
session.close()    #关闭session对象
print(frank.name)    #此时会报错DetachedInstanceError,因为此时是Detached状态。

student = Student(Sno='10001', Sname='Frnak', Ssex='M', Sage=22, Sdept='SFS')
session.add(student)
session.commit()  # 不要忘了commit
session.close()

还有一个添加多个数据项的方法:add_all。不过,要先自定义一个students列表

session.add_all(students)
session.commit()
session.close()

session.query(Student).filter(Student.Sname == 'Frank').first()
session.query(Student).filter_by(Sname == 'Frank').first()
# 注意filter与filter_by的区别

target = session.query(Student).filter(Student.Sname == "Kim").first()
target.Sname = "Kimmy"
session.commit()
session.close()
# 修改数据,先要找到目标数据。

target = session.query(Student).get("10001")
session.delete(target)
session.commit()
# 一样,要删除数据,就要先找到目标数据。

一对多

from sqlalchemy import create_engine, Column, String, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship

engine = create_engine('mysql+pymysql://root:@ROOT_root_123@localhost:3306/blog?charset=utf8')
Session = sessionmaker(bind=engine)
Base = declarative_base()


class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(20), nullable=False)

    addresses = relationship('Address', backref='users')


class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    address = Column(String(20), nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'))  
View Code

请注意,设置外键的时候用的是表名.字段名。其实在表和表类的抉择中,只要参数是字符串,往往是表名;如果是对象则是表类对象

一对一

from sqlalchemy import create_engine, Column, String, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship

engine = create_engine("mysql+pymysql://root:@ROOT_root_123")
Session = sessionmaker(bind=engine)
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(20), nullable=False)

    addresses = relationship('Address', backref='users', uselist=False)


class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    address = Column(String(20), nullable=False)
    user_id = Column(Integer, ForeignKey('users.id')) 
View Code

多对多

from sqlalchemy import create_engine, Column, String, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship

engine = create_engine('mysql+pymysql://root:@ROOT_root_123@localhost:3306/blog?charset=utf8')
Session = sessionmaker(bind=engine)
Base = declarative_base()
session = Session()


class Class(Base):
    __tablename__ = 'class'
    class_id = Column(Integer, primary_key=True)
    name = Column(String(20), nullable=False)
    class_teacher = relationship('ClassTeacher', backref='class')


class Teacher(Base):
    __tablename__ = 'teacher'
    teacher_id = Column(Integer, primary_key=True)
    name = Column(String(20), nullable=False)
    teacher_class = relationship('ClassTeacher', backref='teacher')


class ClassTeacher(Base):
    __tablename__ = 'class_teacher'  # 这就是所谓的一张视图表,没有实际存在数据,但是凭借关系型数据库的特点可以体现出一些数据关系
    teacher_id = Column(Integer, ForeignKey('teacher.teacher_id'), primary_key=True)
    class_id = Column(Integer, ForeignKey('class.class_id'), primary_key=True)
    # 这张第三表中有两个主键,表示不能有class_id和teacher_id都相同的两项

_class = session.query(Class).filter(Class.name == '三年二班').first()

for class_teacher_rel in _class.class_teacher
View Code

采用:https://blog.csdn.net/weixin_44080811/article/details/90030744

原文地址:https://www.cnblogs.com/Pythonzrq/p/13305700.html