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'))
请注意,设置外键的时候用的是表名.字段名。其实在表和表类的抉择中,只要参数是字符串,往往是表名;如果是对象则是表类对象
一对一
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'))
多对多
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
采用:https://blog.csdn.net/weixin_44080811/article/details/90030744