【无标题】

2 sqlalchemy快速使用

# sqlalchemy 是一个企业级的orm框架
# django 的orm框架---》只能用在django框架中,不能用在别的位置
# sqlalchemy可以单独使用,也可以用在其他框架中
	-flask : sqlalchemy
    -fastapi:sqlalchemy
    
# python界的orm框架
	-django orm
    -sqlalchemy
    -peewee
    
# 组成
Engine,框架的引擎
Connection Pooling ,数据库连接池
Dialect,选择连接数据库的DB API种类
Schema/Types,架构和类型
SQL Exprression Language,SQL表达式语言


# 安装 
pip3 install  sqlalchemy


# SQLAlchemy本身无法操作数据库,其必须依赖pymsql等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:

MySQL-Python
    mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
    
pymysql
    mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
    
MySQL-Connector
    mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
    
cx_Oracle
    oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
    
更多:http://docs.sqlalchemy.org/en/latest/dialects/index.html


# django中如何反向生成models
python manage.py inspectdb > app/models.py

3 sqlalchemy原生操作



# 操作原生sql ---》用得少
import pymysql
import threading
# 1 导入
from sqlalchemy import create_engine
from sqlalchemy.engine.base import Engine
# 2 创建引擎
engine = create_engine(
    "mysql+pymysql://root:1234@127.0.0.1:3306/cnblogs",
    max_overflow=0,  # 超过连接池大小外最多创建的连接
    pool_size=5,     # 连接池大小
    pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
    pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
)

# 3 使用引擎,拿到链接
# conn = engine.raw_connection()
# # 4 剩下的一样了
# cursor=conn.cursor(pymysql.cursors.DictCursor)
# cursor.execute('select * from article limit 10')
# res=cursor.fetchall()
#
# print(res)


## 多线程测试:
def task(arg):
    conn = engine.raw_connection()
    cursor = conn.cursor()
    cursor.execute(
        "select * from article"
    )
    result = cursor.fetchall()
    print(result)
    cursor.close()
    conn.close()

for i in range(20):
    t = threading.Thread(target=task, args=(i,))
    t.start()

4 sqlalchemy操作表

# 1 建个 models.py  里面写 表模型
# 2 把表模型---》同步到数据库中
# 3 增删查改

4.1 创建删除表

# 1 导入
import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index

Base = declarative_base()  # Base 当成 models.Model


# 2 创建表模型
class User(Base):
    __tablename__ = 'users'  # 表名
    # 写字段
    id = Column(Integer, primary_key=True, autoincrement=True)  # id 主键
    name = Column(String(32), index=True, nullable=False)  # name列,索引,不可为空
    email = Column(String(32), unique=True)
    # datetime.datetime.now不能加括号,加了括号,以后永远是当前时间
    ctime = Column(DateTime, default=datetime.datetime.now)
    extra = Column(Text)


# 3 没有命令---》后期使用第三方模块,可以有命令
# 目前需要手动做
# sqlalchemy 不能创建数据库,能创建表,删除表,不能删除增加字段(第三方模块)
# 3.1 创建引擎
engine = create_engine(
    "mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy01",
    max_overflow=0,  # 超过连接池大小外最多创建的连接
    pool_size=5,  # 连接池大小
    pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
    pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
)
## 3.2 把表模型同步到数据库中
Base.metadata.create_all(engine)

# 3.3 删除表
# Base.metadata.drop_all(engine)

4.2 简单操作

from models import User

from sqlalchemy import create_engine

# 1 创建引擎
engine = create_engine(
    "mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy01",
    max_overflow=0,  # 超过连接池大小外最多创建的连接
    pool_size=5,  # 连接池大小
    pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
    pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
)

# 2 orm操作--》借助于 engine 得到session(conn)对象
from sqlalchemy.orm import sessionmaker

Connection = sessionmaker(bind=engine)
conn = Connection()
# 3 使用conn---》进行orm操作
# 3.1 增加数据
# user = User(name='lqz', email='3@qq.com')
# # 插入到数据库
# conn.add(user)  # 放个对象
# # 提交
# conn.commit()
# # 关闭链接
# conn.close()


# 3.2 查询数据
# 查询User表中id为1的所有记录--》放到列表中
# res=conn.query(User).filter_by(id=1).all()
# print(res)

## 3.3 删除
# res = conn.query(User).filter_by(name='lqz').delete()
# print(res)
# conn.commit()

## 3.4 修改

# res=conn.query(User).filter_by(name='9999').update({'extra':'xxsss'})
# conn.commit()

1 一对多关系

1.1 关系

import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index

Base = declarative_base()  # Base 当成 models.Model


### 单表
class User(Base):
    __tablename__ = 'users'  # 表名
    # 写字段
    id = Column(Integer, primary_key=True, autoincrement=True)  # id 主键
    name = Column(String(32), index=True, nullable=False)  # name列,索引,不可为空
    email = Column(String(32), unique=True)
    # datetime.datetime.now不能加括号,加了括号,以后永远是当前时间
    ctime = Column(DateTime, default=datetime.datetime.now)
    extra = Column(Text)

    def __str__(self):
        return self.name

    def __repr__(self):
        return self.name


# 一对多 :一个兴趣被多个人喜欢  一个人只喜欢一个兴趣
class Hobby(Base):
    __tablename__ = 'hobby'
    id = Column(Integer, primary_key=True)
    caption = Column(String(50), default='篮球')

    def __str__(self):
        return self.caption

    def __repr__(self):
        return self.caption


class Person(Base):
    __tablename__ = 'person'
    id = Column(Integer, primary_key=True)
    name = Column(String(32), index=True, nullable=True)
    # hobby指的是tablename而不是类名,uselist=False
    # 外键关联--》强外键--》物理外键
    hobby_id = Column(Integer, ForeignKey("hobby.id"))

    # 跟数据库无关,不会新增字段,只用于快速连表操作
    # 类名,backref用于反向查询
    hobby = relationship('Hobby', backref='pers')

    def __str__(self):
        return self.name

    def __repr__(self):
        return self.name

1.2 操作

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Hobby, Person, User

engine = create_engine(
    "mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy02",
    max_overflow=0,  # 超过连接池大小外最多创建的连接
    pool_size=5,  # 连接池大小
    pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
    pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
)

Session = sessionmaker(bind=engine)
session = Session()

# 1  增加 Hobby
# hobby = Hobby(caption='足球')
# hobby1 = Hobby()
# session.add_all([hobby, hobby1])
# session.commit()

# 2 增加Person
# p1 = Person(name='彭于晏', hobby_id=1)
# p2 = Person(name='刘亦菲', hobby_id=2)
# session.add_all([p1, p2])
# session.commit()

# 3 简便方式增加person---》增加Person,直接新增Hobby
# hobby1 = Hobby(caption='乒乓球')
# p1 = Person(name='彭于晏', hobby=hobby1) # 前提是必须有relationship
# session.add(p1)
# session.commit()

# # 4 基于对象的跨表查询---正向
# per=session.query(Person).filter_by(name='彭于晏').first()
# print(per)
# # 正向
# print(per.hobby.caption)

# 5 基于对象的跨表查询---正向
hobby=session.query(Hobby).filter_by(caption='篮球').first()
print(hobby)
# 反向--->拿到多条
print(hobby.pers)
print(hobby.pers[0].name)  # 列表套对象

2 多对多关系

1.1 关系

import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index

Base = declarative_base()  # Base 当成 models.Model


### 单表
class User(Base):
    __tablename__ = 'users'  # 表名
    # 写字段
    id = Column(Integer, primary_key=True, autoincrement=True)  # id 主键
    name = Column(String(32), index=True, nullable=False)  # name列,索引,不可为空
    email = Column(String(32), unique=True)
    # datetime.datetime.now不能加括号,加了括号,以后永远是当前时间
    ctime = Column(DateTime, default=datetime.datetime.now)
    extra = Column(Text)

    def __str__(self):
        return self.name

    def __repr__(self):
        return self.name


# 一对多 :一个兴趣被多个人喜欢  一个人只喜欢一个兴趣
class Hobby(Base):
    __tablename__ = 'hobby'
    id = Column(Integer, primary_key=True)
    caption = Column(String(50), default='篮球')

    def __str__(self):
        return self.caption

    def __repr__(self):
        return self.caption


class Person(Base):
    __tablename__ = 'person'
    id = Column(Integer, primary_key=True)
    name = Column(String(32), index=True, nullable=True)
    # hobby指的是tablename而不是类名,uselist=False
    # 外键关联--》强外键--》物理外键
    hobby_id = Column(Integer, ForeignKey("hobby.id"))

    # 跟数据库无关,不会新增字段,只用于快速连表操作
    # 类名,backref用于反向查询
    hobby = relationship('Hobby', backref='pers')

    def __str__(self):
        return self.name

    def __repr__(self):
        return self.name


# 多对多
class Boy2Girl(Base):
    __tablename__ = 'boy2girl'
    id = Column(Integer, primary_key=True, autoincrement=True)
    girl_id = Column(Integer, ForeignKey('girl.id'))
    boy_id = Column(Integer, ForeignKey('boy.id'))
    # boy = relationship('Boy', backref='boy')


class Girl(Base):
    __tablename__ = 'girl'
    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)


class Boy(Base):
    __tablename__ = 'boy'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(64), unique=True, nullable=False)

    # 与生成表结构无关,仅用于查询方便,放在哪个单表中都可以--等同于manytomany
    girls = relationship('Girl', secondary='boy2girl', backref='boys')


if __name__ == '__main__':
    # 3.1 创建引擎
    engine = create_engine(
        "mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy02",
        max_overflow=0,  # 超过连接池大小外最多创建的连接
        pool_size=5,  # 连接池大小
        pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
        pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
    )
    ## 3.2 把表模型同步到数据库中
    Base.metadata.create_all(engine)

    # 3.3 删除表
    # Base.metadata.drop_all(engine)

1.2 操作

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Hobby, Person, User, Boy, Girl, Boy2Girl

engine = create_engine(
    "mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy02",
    max_overflow=0,  # 超过连接池大小外最多创建的连接
    pool_size=5,  # 连接池大小
    pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
    pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
)

Session = sessionmaker(bind=engine)
session = Session()

# 1  增加 Boy
# boy = Boy(name='王小刚')
# boy2 = Boy(name='王小明')
# boy3 = Boy(name='王小勇')
# session.add_all([boy,boy2,boy3])
# session.commit()
# 2 增加Girl
# girl = Girl(name='张小华')
# girl2 = Girl(name='刘小红')
# girl3 = Girl(name='李小丽')
# session.add_all([girl3, girl2, girl])
# session.commit()
# 3 增加Boy2Girl
# obj1=Boy2Girl(boy_id=1,girl_id=1)
# obj2=Boy2Girl(boy_id=1,girl_id=2)
# obj3=Boy2Girl(boy_id=1,girl_id=3)
# session.add_all([obj2, obj3, obj1])
# session.commit()

# ------

# 3 简便方式增加

# obj2=Girl(name='张亦菲')
# obj3=Girl(name='李娜扎')
# obj1=Boy(name='张小勇',girls=[obj2,obj3])
#
# session.add(obj1)
# session.commit()

# # 4 基于对象的跨表查询---正向
# boy=session.query(Boy).filter_by(name='张小勇').first()
# print(boy.girls[0].name)


# 5 基于对象的跨表查询---反向
girl=session.query(Girl).filter_by(name='张亦菲').first()
print(girl.boys)

3 scoped线程安全

# session 对象,集成到flask中去,要把session对象做成全局(大家公用),还是每个视图函数独有一个(每次都要实例化得到这个session对象)


# 每个视图函数独有一个---》每次都要实例化---》sqlalchemy提供了一种方式,让咱们使用全局的一个session,但是每个视图函数中使用的都是不同的  request,session都是这种实现机制


# sqlalchemy提供了一种,在不同线程中,虽然使用全局 session,实际上每个线程自己独有一个session
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import Users
from threading import local
engine = create_engine("mysql+pymysql://root:lqz123?@127.0.0.1:3306/sqlalchemy01", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine)

"""
# 线程安全,基于本地线程实现每个线程用同一个session
# 特殊的:scoped_session中有原来方法的Session中的一下方法:

public_methods = (
    '__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
    'close', 'commit', 'connection', 'delete', 'execute', 'expire',
    'expire_all', 'expunge', 'expunge_all', 'flush', 'get_bind',
    'is_modified', 'bulk_save_objects', 'bulk_insert_mappings',
    'bulk_update_mappings',
    'merge', 'query', 'refresh', 'rollback',
    'scalar'
)
"""
# session=Session() # 不是线程安全---》多线程并发情况下---》用的是同一个,就会出现混乱
#scoped_session类并没有继承Session,但是却又它的所有方法

# 以后在多线程,协程情况下,使用这个session,就没有并发安全的问题
# 原理是什么? 内部使用了threading包下local对象,   local.session  在不同线程下执行这个取值或赋值,使用的都是当前线程自己的

# 线程1   local.a=100  后续的操作中--->取local.a--->永远是当时这条线程中放进去的a ,也就是100
# 线程2   local.a=999   --->取local.a--->永远是当时这条线程中放进去的a ,也就是999

#local对象如何实现的线程安全呢? 内部维护了一个字典,字典的key是线程id号,value值是
# l=local()  #  {}
# # 线程1 
# l.session=线程1的session  # {线程1的id号:{session:新session}}
# 
# # 线程2 
# l.session# {线程1的id号:{session:新session},线程2的id号:{session:线程2的session}}



# 本质就是,不同线程,使用自己线程的那个session
# scoped_session 不是Session类的对象,但是他有 Session类对象的所有方法----》通过装饰器,装进去的
session = scoped_session(Session)
# ############# 执行ORM操作 #############
obj1 = Users(name="lqz4",email='3533@qq.com')
session.add(obj1)

# 提交事务
session.commit()
# 关闭session
session.close()

4 基本增删查改

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import User, Person, Hobby, Boy, Girl, Boy2Girl
from sqlalchemy.sql import text

engine = create_engine("mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy02", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine)
session = scoped_session(Session)

# 1 添加, add   add_all

# 2 删除
# 2.1 session.query(Users).filter_by(id=1).delete()
# 2.1 session.delete(对象)
# user = session.query(User).filter_by(id=1).first()
# session.delete(user)
# session.commit()

#  修改
#  1 方式一:
# session.query(Boy).filter_by(id=1).update({'name':'lqz'})
# session.commit()

# # 2 方式二  类名.属性名,作为要修改的key
# session.query(Boy).filter_by(id=4).update({Boy.name:'lqz1'})
# session.commit()


# # id为4的人的名字后+  _nb   类似于django的 F 查询
# session.query(User).filter_by(id=2).update({'name':User.name+'_nb'},synchronize_session=False) # 字符串拼接
# session.query(User).filter_by(id=2).update({'id':User.id+6}, synchronize_session="evaluate") # 数字之间加
# session.commit()


# # 3 方式三:
# 对象.name='xxx'
#session.add(对象)
# boy=session.query(Boy).filter_by(id=1).first()
# boy.name='xxzzyy'
# session.add(boy) # 有id就是修改,没有就是新增
# session.commit()



### 4 查询---》基本查询
# 4.1 filter_by  写条件
# res=session.query(User).filter_by(name='lqz_nb',id=8).first()
# res=session.query(User).filter_by(name='lqz').all()  # 放在列表中 不是queryset对象



# 4.2 filter  写表达式
# res=session.query(User).filter(User.name=='lqz_nb').first()
# res=session.query(User).filter(User.id>=3).all()
# res=session.query(User).filter(User.name!='lqz').all()


# 4.3 只查表中某几个字段,并重命名
# select name as xx,age from user;
# res=session.query(User.name.label('xx'), User.email)

# select name,email from user;
# res=session.query(User.name, User.email).all()
# res=session.query(User)


# 4.4 条件可以使用text自己拼凑
# select * from user where id< 224 and name=lqz order by id
# res = session.query(User).filter(text("id<:value and name=:name")).params(value=224, name='lqz_nb').order_by(User.id).all()
# print(res)



## 4.5 直接原生sql
# SELECT * FROM users where name=lqz
# res = session.query(User).from_statement(text("SELECT * FROM users where name=:name")).params(name='lqz_nb').all()
res = session.query(User).from_statement(text("SELECT * FROM users where name=:name")).params(name='张三')
print(res)

1 常用查询

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import Users,Person,Hobby,Boy,Girl
from sqlalchemy.sql import text
engine = create_engine("mysql+pymysql://root:lqz123?@127.0.0.1:3306/sqlalchemy01", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine)
session = scoped_session(Session)





#### 5  高级查询--只需要看懂
#5.1  filter_by写 条件  会了
# ret = session.query(Users).filter_by(name='lqz').all()

#5.2 表达式,and条件连接  between
# ret = session.query(Users).filter(Users.id > 1, Users.name == 'lqz').all()

# 5.3 between
# select * from users where user.id between 4 and 10 and name=lqz;
# ret = session.query(Users).filter(Users.id.between(4, 10), Users.name == 'lqz')

# 5.4 in 条件
# ret = session.query(Users).filter(Users.id.in_([1,4,5])).all()

# 5.5 ~非,除。。外
# ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all()

# 5.5 二次筛选
# select * from users where id in (select id from users where name = lqz);
# ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='lqz'))).all()

## 5.6 and 和 or条件
from sqlalchemy import and_, or_
# #or_包裹的都是or条件,and_包裹的都是and条件
# ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'lqz')).all()
# ret = session.query(Users).filter(Users.id > 3, Users.name == 'lqz').all() # 根上面一样

# select * from users where id<=2 or name =lqz;
# ret = session.query(Users).filter(or_(Users.id <= 2, Users.name == 'lqz')).all()

# select * from users where id <2 or (name=lqz and id>3) or extra !='';
# ret = session.query(Users).filter(
#     or_(
#         Users.id < 2,
#         and_(Users.name == 'lqz', Users.id > 3),
#         Users.extra != ""
#     ))


# 5.7 like
# # 通配符,以e开头,不以e开头
# select * from users where name like l%;
# ret = session.query(Users).filter(Users.name.like('l%')).all()
# ret = session.query(Users).filter(~Users.name.like('l%')).all()


#5.8  限制,用于分页,区间
# ret = session.query(Users)[1:2]  # 去第一条到第二条  其实就是只取 第二条,从0开始

# 5.9 排序,根据name降序排列(从大到小)
# ret = session.query(Users).order_by(Users.name.desc()).all()
# ret = session.query(Users).order_by(Users.name.asc())
# ret = session.query(Users).order_by(Users.name).all()

# #第一个条件重复后,再按第二个条件升序排
# ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()


#5.10 分组
from sqlalchemy.sql import func
# select name from users group by name;  一旦分组,只能查询 分组字段和 聚合函数的字段
# ret = session.query(Users.name).group_by(Users.name).all()

# #分组之后取最大id,id之和,最小id 和名字
ret = session.query(
    func.max(Users.id),
    func.sum(Users.id),
    func.min(Users.id),func.count(Users.id),Users.name).group_by(Users.name).all()

# #haviing筛选
# select max(id),sum(id),min(id),count(id),name from users group by name where id >2 having min(id)>2;
# ret = session.query(
#     func.max(Users.id),
#     func.sum(Users.id),
#     func.min(Users.id),func.count(Users.id),Users.name).filter(Users.id>2).group_by(Users.name).having(func.min(Users.id) >2)


# 5.11  连表(默认用forinkey关联)
# select * from person,hobby where user.hobby_id=hobby.id;
# ret = session.query(Person, Hobby).filter(Person.hobby_id == Hobby.id).all()

# #join表,默认是inner join
# select * from person inner join hobby on person.hobby_id=hobby.id;
# ret = session.query(Person).join(Hobby).all()

# #isouter=True 外连,表示Person left join Hobby,没有右连接,反过来即可
# select * from person left join hobby on person.hobby_id=hobby.id;
# ret = session.query(Person).join(Hobby, isouter=True).all()
# ret = session.query(Hobby).join(Person, isouter=True).all()  # 右链接

# 没有指定链表条件,默认以外键关联
# # 自己指定on条件(连表条件),第二个参数,支持on多个条件,用and_,同上
# select * from Person left join hobby on person.id=hobby.id;  # sql 没有意义,只是讲案例
# ret = session.query(Person).join(Hobby,Person.id==Hobby.id, isouter=True)



# 5.12 union和union all
# # 组合(了解)UNION 操作符用于合并两个或多个 SELECT 语句的结果集
# #union和union all的区别?
# q1 = session.query(Boy.id,Boy.name).filter(Boy.id > 1)
# q2 = session.query(Girl.id,Girl.name).filter(Girl.id < 10)
# ret = q1.union(q2).all()
#
# q1 = session.query(Boy.name).filter(Boy.id > 1)
# q2 = session.query(Girl.name).filter(Girl.id < 10)
# ret = q1.union_all(q2).all()
# print(ret)

# 提交事务
session.commit()
# 关闭session
session.close()

2 flask-sqlalchemy

2.1 flask-sqlalchemy集成到flask中

## 借助于flask-sqlalchemy
	1 导入 from flask_sqlalchemy import SQLAlchemy
    2 实例化得到对象
    	db = SQLAlchemy()
    3  将db注册到app中
    	db.init_app(app)
    ------2,3 可以合并为db = SQLAlchemy(app)--------
    
    4 视图函数中使用session
    	全局的db.session  # 线程安全的
    5 models.py 中继承Model
    	db.Model
    6 写字段 
    	username = db.Column(db.String(80), unique=True, nullable=False)
    7 配置文件中加入
    SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root@127.0.0.1:3306/ddd?charset=utf8"
    SQLALCHEMY_POOL_SIZE = 5
    SQLALCHEMY_POOL_TIMEOUT = 30
    SQLALCHEMY_POOL_RECYCLE = -1
    # 追踪对象的修改并且发送信号
    SQLALCHEMY_TRACK_MODIFICATIONS = False

3 flask-migrate

# 1 数据库肯定要自己创建
# 2 创建表,增加删除字段---》手动做---》django 有两个命令---》自动做
	-有没有种方案,跟djagno一样,自动记录,自动迁移
    
    
    
# 3 django中:
	python manage.py makemigrations
    python manage.py migrate
    
    
# 4 第三方模块:flask-migrate--》完成跟django一样--》命令稍微有些不同



# https://github.com/miguelgrinberg/Flask-Migrate/
pip3 install Flask-Migrate --upgrade
4.0.6




####### 使用
from flask_migrate import Migrate

app = Flask(__name__)
app.config.from_pyfile('./settings.py')
db = SQLAlchemy(app)
# db.init_app(app)
migrate = Migrate(app, db) # flask 就会多出好几个命令---》

# flask --app manage:app db init  # 初始化,第一次执行,以后再也不执行了,它执行完,会出现一个migrations文件夹
# flask --app manage:app db migrate # django中的makemigrations 是一模一样
# flask --app manage:app db upgrade  # 跟django的migrate一样



# flask上其他第三方插件
	cors
    token
    cache
    restful

3 flask 项目

#  网上开源的---》前后端混合
	layui---》rbac的权限控制
    下载下来---》运行---》研究功能

# 项目--》微电影网站--》前后端混合的--》抛起来
	1 pycharm打开
    2 找到models 把一些注释打开,创建数据库 movie,把main打开
    	-执行 python models.py  # 创建表,插入记录
    3 把原来注释加上
    4 __init__ 改真正的数据库地址
    5 在cmd中执行  python manage.py runserver
    	http://127.0.0.1:5000/admin/
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值