首页 > 其他分享 >flask08_days

flask08_days

时间:2024-03-10 22:59:25浏览次数:14  
标签:__ name Column days session 线程 flask08 id

一对多关系

 关系

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

操作

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

engine = create_engine(
    "mysql+pymysql://root:[email protected]: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)  # 列表套对象

多对多关系

 关系

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:[email protected]: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)

操作

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:[email protected]: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)

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:[email protected]: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='[email protected]')
session.add(obj1)

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

基本增删查改

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:[email protected]: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)

 

标签:__,name,Column,days,session,线程,flask08,id
From: https://www.cnblogs.com/wzh366/p/18065025

相关文章

  • flask_06days
    flask-session#django中session都是放在django-session表中 #flask的session,是加密后放到cookie中了#现在向把session存在服务端--——》不放在cookie中了 -表中:跟djagno默认一样-缓存(redis):性能高#第三方模块:解决了这个问题--》flask-sessio......
  • flask_05days __蓝图
    蓝图#blueprint翻译过来的---》把项目分到多个py文件---》以后常用 -划分项目目录 蓝图小项目目录划分(只有一个app)大型项目-目录划分(多个app)——————————————————————————蓝图就是把我们应用目录的模块注册到Flask类,充当一个中间人的角色通过......
  • flask_04days
    cbv源码分析 执行流程#1app.add_url_rule('/user','user',UserView.as_view('user'))-第三个参数,放视图函数的内存地址---》UserView.as_view('user')是函数内存地址#2UserView中找类方法as_view--》返回值是一个函数内存地址-UserView中没有-MethodVi......
  • Coderforces 1699E Three Days Grace
    考虑到这个是\(\max-\min\)的形式,可以先固定下一维。考率固定下\(\min\),这样就只需要使\(\max\)尽量小即可。考虑对于\(x\),可以拆为\(i\)和\(x/i\),然后又分成子问题去考虑。于是可以\(\text{DP}\),令\(f_{i,j}\)为\(\min\gei\),拆\(j\)的最小的\(\max\)。......
  • 爬虫_06days
    #1scrapy框架架构 -爬虫:我们写爬取起始地址,解析数据的位置-引擎:控制数据流向-调度器:控制爬取的先后-下载器:负责下载,建立在twisted之上-pipline:持久化#2目录结构 -创建爬虫命令:scrapygensipder名字网址-运行爬虫:scrapycraw......
  • 爬虫_05days ↑
    scrapy架构介绍#scrapy:爬虫框架---》使用scrapy创建爬虫项目#pipinstallscrapy#创建scrapy项目 scrapystartproject项目名#架构spiders:爬虫,主要是咱们写代码的地方---》设置起始爬取的地址--》解析数据engine:引擎,大总管,控制数据的整体流动scheduler:调度器,待爬取的地址......
  • 爬虫_04days
    自动登录cnblogs--获取cookieimporttimeimportjsonfromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.chrome.optionsimportOptions#####绕过浏览器检测到自动化软件控制options=Options()options.add_argum......
  • 爬虫03_days
    selenium介绍#1由于requests不能执行js---》逐个分析ajax请求--》模拟发送获取数据 -使用requests爬取的数据很大概率跟在浏览器中看到的不一样-requests不能执行js#2seleniumselenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaS......
  • 爬虫_02days
    免费代理池搭建#代理有免费和收费代理#代理有http代理和https代理#匿名度 -高匿:隐藏访问者ip-透明:服务端能拿到访问者ip-作为后端,如何拿到使用代理人的ip -请求头中:x-forword-for-如果一个HTTP请求到达服务器之前,经过了三个代理Proxy1、Proxy2、Proxy3......
  • pandas.Timedelta(days=1) 可以 与 datetime.timedelta(days=1) 效果一致
    pandas.Timedelta(days=1)可以与datetime.timedelta(days=1)效果一致https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timedelta.html#pandas-timedelta但pandas.Timedelta可以有其他写法......