SQLAlchemy(十)
ORM操作在实际项目中的应用非常多,涉及到的框架也是根据不同的项目有不同的处理模块,不过操作流程和步骤都是大同小异基本没有什么太大变化,唯一需要注意的就是在实际操作过程中你要使用的ORM框架的处理性能和是否支持事务、是否支持分布式等特性来进行确定使用哪个ORM框架进行操作,一般在python程序中ORM操作都是对mysqldb和pymysql这样的底层模块进行的封装处理。例如文章中要讲解的sqlalchemy就是底层封装mysqldb的实现,不过我们的在使用过程中需要使用pymysql进行替代。
1、安装
$ pip install sqlalchemy
安装完成之后,可以通过引入sqlalchemy进行版本查看,确认sqlalchemy是否安装成功
2、连接引擎
使用sqlalchemy进行数据库操作,首先我们需要建立一个指定数据库的连接引擎对象。建立引擎对象的方式被封装在了sqlalchemy.create_engine函数中,通过指定的数据库连接信息就可以进行创建。
创建数据库连接引擎时参数设置语法:
# 引入建立引擎的模块
from sqlalchemy import create_engine # pymsql创建引擎连接
# mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
engine = create_engine("mysql+pymysql://root:123456@192.168.3.109:3306/test", encoding="utf-8", echo=True)
指定的数据库连接字符串表示了目标数据库的配置信息;encoding配置参数指定了和和数据库之间交换的数据的编码方式,同时echo参数表示随时在控制台展示和数据库之间交互的各种信息。
create_engine()函数返回的是sqlalchemy最核心的接口之一,该引擎对象会根据开发人员指定的数据库进行对应的sql api的调用处理。
3、连接会话
创建了数据库连接引擎对象之后,我们需要获取和指定数据库之间的连接,通过连接进行数据库中数据的增删改查操作,和数据库的连接我们称之为和指定数据库之间的会话。
我们使用 sessionmaker 方法创建session。
# 引入创建session连接会话的模块
from sqlalchemy.orm import sessionmaker # 创建一个连接会话对象;需要指定是和哪个数据库引擎之间的会话
Session = sessionmaker(bind=engine)
session = Session() # 如果在创建会话的时候没有指定数据库引擎,可以通过如下的方式完成引擎绑定操作
# Session = sessionmaker()
# Session.configure(bind=engine)
# session = Session()
此时的session不是线程安全的,并且我们一般session对象都是全局的,那么在多线程情况下,当多个线程共享一个session时,数据处理就会发生错误。为了保证线程安全,需使用scoped_session方法。
# 引入创建session连接会话的模块
from sqlalchemy.orm import sessionmaker, scoped_session # 创建一个连接会话对象;需要指定是和哪个数据库引擎之间的会话
Session = scoped_session(sessionmaker(bind=engine))
session = Session()
4、ORM之Object操作
我们的程序中的对象要使用sqlalchemy的管理,实现对象的orm操作,就需要按照框架指定的方式进行类型的创建操作,sqlalchemy封装了基础类的声明操作和字段属性的定义限制方式,开发人员要做的事情就是引入需要的模块并在创建对象的时候使用它们即可
基础类封装在sqlalchemy.ext.declarative.declarative_base模块中
字段属性的定义封装在sqlalchemy模块中,通过sqlalchemy.Column定义属性,通过封装的Integer、String、Float等定义属性的限制
常用的SQLAlchemy字段类型
类型名 | python中类型 | 说明 |
---|---|---|
Integer | int | 普通整数,一般是32位 |
SmallInteger | int | 取值范围小的整数,一般是16位 |
BigInteger | int或long | 不限制精度的整数 |
Float | float | 浮点数 |
Numeric | decimal.Decimal | 普通整数,一般是32位 |
String | str | 变长字符串 |
Text | str | 变长字符串,对较长或不限长度的字符串做了优化 |
Unicode | unicode | 变长Unicode字符串 |
UnicodeText | unicode | 变长Unicode字符串,对较长或不限长度的字符串做了优化 |
Boolean | bool | 布尔值 |
Date | datetime.date | 时间 |
Time | datetime.datetime | 日期和时间 |
LargeBinary | str | 二进制文件 |
常用的SQLAlchemy列选项
选项名 | 说明 |
---|---|
primary_key | 如果为True,代表表的主键 |
unique | 如果为True,代表这列不允许出现重复的值 |
index | 如果为True,为这列创建索引,提高查询效率 |
nullable | 如果为True,允许有空值,如果为False,不允许有空值 |
default | 为这列定义默认值 |
常用的SQLAlchemy关系选项
选项名 | 说明 |
---|---|
backref | 在关系的另一模型中添加反向引用 |
primary join | 明确指定两个模型之间使用的联结条件 |
uselist | 如果为False,不使用列表,而使用标量值 |
order_by | 指定关系中记录的排序方式 |
secondary | 指定多对多中记录的排序方式 |
secondary join | 在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结条件 |
4.1 创建基础类
# 引入需要的模块
from sqlalchemy.ext.declarative import declarative_base # 创建基础类
BaseModel = declarative_base()
4.2 创建模型类
定义模型类必须继承自之前创建的基础类BaseModel,同时通过指定__tablename__确定和数据库中某个数据表之间的关联关系,指定某列类型为primary_key设定的主键,其他就是通过Column指定的自定义属性了。
sqlalchemy会根据指定的__tablename__和对应的Column列字段构建自己的accessors访问器对象,这个过程可以称为instrumentation,经过instrumentation映射的类型就可以进行数据库中数据的操作了。
# 引入需要的模块
from sqlalchemy import Column, String, Integer, ForeignKey # 创建模型类
class User(BaseModel):
# 定义表名
__tabelname__ = "tbl_user" # 创建字段类型
id = Column(Integer, primary_key=True)
name = Column(String(50))
age = Column(Integer) class Author(BaseModel):
__tablename__ = "tbl_author" id = Column(Integer, primary_key=True)
name = Column(String(50)) class Book(BaseModel):
__tablename__ = "tbl_book" id = Column(Integer, primary_key=True)
book_name = Column(String(50))
# ForeignKey 定义外键,需要导入
author_id = Column(Integer, ForeignKey("tbl_author.id"))
4.3 模型类映射操作
完成了模型类的定义之后,Declarative会通过python的metaclass对模型类进行操作,根据定义的模型类创建table对象,构建程序中类型和数据库table对象之间的映射mapping关系。
通过类型对象的metadata可以实现和数据库之间的交互,有需要时可以通过metadata发起create table操作,通过Base.metadata.create_all()进行操作,该操作会检查目标数据库中是否有需要创建的表,不存在的情况下创建对应的表。
# 删除所有模型类创建的表格(慎用)
BaseModel.metadata.drop_all(engine)
# 创建所有模型类的表格,有则不创建
BaseModel.metadata.create_all(engine)
5、数据的增、查、改、删
5.1 增
在程序代码中根据定义的数据类型创建对象的方式比较简单,创建对象并通过会话对象将数据对象持久化到数据库中。
# 增
user1 = User(name="张三", age=18)
user2 = User(name="李四", age=19)
user3 = User(name="王五", age=20)
# 将单个对象加入到会话对象中
session.add(user1)
# 将多个对象加入到会话对象中
session.add_all([user2, user3])
# 提交数据
session.commit()
5.2 查
Session是sqlalchemy和数据库交互的桥梁,Session提供了一个Query对象实现数据库中数据的查询操作
5.2.1 基础查询
查询所有数据
# 返回User对象所有字段的所有信息,返回结果为对象列表
session.query(User)
排序查询
# 指定排序查询
session.query(User).order_by(User.id) # 升序查询
session.query(User).order_by(-User.id) # 降序查询
session.query(User).order_by(-User.id, User.name) # 多条件排序查询
查询指定列
# 返回User对象字段为id和name的所有信息,返回结果为元组列表
session.query(User.id, User.name)
为字段取别名
# 为字段取别名
session.query(User.id, User.name.label("n"))
# 对应SQL语句:SELECT tbl_user.id AS tbl_user_id, tbl_user.name AS n FROM tbl_user
分页查询
# 使用limit()+offset()切片分页
# limit()限制返回条数
# offset()偏移
ret = session.query(User).limit(3).offset(2).all() # 返回第2条以后的3条数据,即第3至第5条数据
print(ret) # 使用slice()切片分页
ret = session.query(User).slice(2, 5).all() # 返回第3至第5条数据
print(ret) # 使用python列表切片分页
ret = session.query(User).all()[2:5] # 返回第3至第5条数据
print(ret)
分组查询
# 分组查询
session.query(User.name).group_by(User.name)
聚合函数
# 查询常用聚合函数
from sqlalchemy.sql import func
session.query(func.max(User.age), # 最大
func.min(User.age), # 最小
func.sum(User.age), # 求和
func.avg(User.age), # 平均
func.count(User.age) # 统计
)
去重
# 去重查询
from sqlalchemy import distinct
session.query(distinct(User.name))
5.2.2 条件筛选
在实际使用过程中经常用到条件查询,主要通过filter和filter_by进行操作,重点讲解使用最为频繁的filter条件筛选函数
等值条件_equals / not equals
# 等于
session.query(User).filter(User.name == "李四")
# 不等于
session.query(User).filter(User.name != "李四")
模糊条件_like/notlike
# 用户名包含“张”
session.query(User).filter(User.name.like("%张%"))
# 用户名不包含“张”
session.query(User).filter(User.name.notlike('%张%'))
范围条件_in / not in
# in
session.query(User).filter(User.id.in_([1, 2, 4])) # not in
session.query(User).filter(~User.id.in_([1, 2, 4]))
空值条件
# 空值
session.query(User).filter(User.name == None)
session.query(User).filter(User.name.is_(None)) # 非空
session.query(User).filter(User.name != None)
session.query(User).filter(User.name.isnot(None))
并且条件
from sqlalchemy import and_
session.query(User).filter(User.name == '张三').filter(User.age == 18)
session.query(User).filter(User.name == '张三', User.age == 18)
session.query(User).filter(and_(User.name == '张三', User.age == 18))
或者条件
from sqlalchemy import or_
session.query(User).filter(or_(User.name == '张三', User.name == '李四'))
5.2.3 多表查询
# 多表查询
session.query(Author.name, Book.book_name).filter(Author.id == Book.author_id)
# 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_author, tbl_book WHERE tbl_author.id = tbl_book.author_id # 内联查询join
session.query(Author.name, Book.book_name).join(Author, Author.id == Book.author_id)
# 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_book INNER JOIN tbl_author ON tbl_author.id = tbl_book.author_id # 左联查询outerjoin。没有右联查询
session.query(Author.name, Book.book_name).outerjoin(Author, Author.id == Book.author_id)
# 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_book LEFT OUTER JOIN tbl_author ON tbl_author.id = tbl_book.author_id # 并集查询
author_name = session.query(Author.name)
book_name = session.query(Book.book_name)
author_name.union(book_name)
# 对应SQL:SELECT anon_1.c_name FROM
# (SELECT tbl_author.name as c_name FROM tbl_author UNION SELECT tbl_book.book_name as c_name FROM tbl_book) AS anon_1
5.2.4 获取查询结果
获取查询对象有这么几种方法one()
,all()
,first(),one(),one_or_none()
,scalar(),以及get()等。
下面对这几个方法的用法及效果做简单解释。
all()
返回查询到的所有的结果。
这个方法比较危险的地方是如果数据量大且没有使用limit
子句限制的话,所有的结果都会加载到内存中。
它返回的是一个列表,如果查询不到任何结果,返回的是空列表。
ret = session.query(User).all()
print(ret) # [<__main__.User object at 0x0000000003894F60>, <__main__.User object at 0x00000000038942E8>]
first()
返回查询到的第一个结果,如果没有查询到结果,返回None
。
ret = session.query(User).first()
print(ret) # <__main__.User object at 0x0000000003894358>
one()
如果只能查询到一个结果,返回它,否则抛出异常。
没有结果时抛sqlalchemy.orm.exc.NoResultFound
,有超过一个结果时抛sqlalchemy.orm.exc.MultipleResultsFound
。
ret = session.query(User).filter(User.id == 2).one()
print(ret) # <__main__.User object at 0x00000000038954A8>
one_or_none()
比起one()
来,区别只是查询不到任何结果时不再抛出异常而是返回None
。
ret = session.query(User).filter(User.id == 2).one_or_none()
print(ret) # <__main__.User object at 0x00000000038954A8>
scalar()
这个方法与.one_or_none()
的效果一样。
如果查询到很多结果,抛出sqlalchemy.orm.exc.MultipleResultsFound
异常。
如果只有一个结果,返回它,没有结果返回None
。
ret = session.query(User).filter(User.id == 2).scalar()
print(ret) # <__main__.User object at 0x00000000038954A8>
get()
这是个比较特殊的方法。它用于根据主键来返回查询结果,因此它有个参数就是要查询的对象的主键。
如果没有该主键的结果返回None
,否则返回这个结果。
ret = session.query(User).get(2)
print(ret) # <__main__.User object at 0x00000000038954A8>
当获取的结果为一个对象时,可以通过 对象.模型类属性 的方式取出值
user = session.query(User).get(2)
print(user) # <__main__.User object at 0x00000000038954A8>
print(user.name) # 李四
5.3 改
# update()更新数据
session.query(User).filter(User.id == 2).update({"name": "李四改"})
session.query(User).filter(User.id >= 4).update({"age": 88})
session.commit()
5.4 删
# delete()删除数据
session.query(User).filter(User.id == 2).delete()
session.query(User).filter(User.id >= 4).delete()
session.commit()
6、执行原生SQL语句
使用原生sql语句需要引入text方法,传入要执行的sql语句,若需要给sql语句传参,需要使用 :param 的方式定义参数名,然后使用 params() 并以键值对的方式传入值
from sqlalchemy import text
session.query(User).from_statement(text('select * from tbl_user where name=:name and age=:age')).params(name='李四', age=19)
session.query(User).from_statement(text('update tbl_user set name=:name where id=:id')).params(name='赵六', id=1)
session.commit()
还有一种类似于pymysql使用 execute() 执行原生sql的方法
ret = session.execute('select * from tbl_user where name=:name', {"name": "赵六"}).fetchall() # 所有数据以元组的形式保存在列表中
print(ret) # [(1, '赵六', 18, 2), (4, '赵六', 18, 2)]
ret = session.execute('select * from tbl_user where name=:name', {"name": "赵六"}).fetchone() # 返回第一条数据,无则为None
print(ret) # (1, '赵六', 18, 2)
附码:
# 引入建立引擎的模块
from sqlalchemy import create_engine
# 引入创建session连接会话的模块
from sqlalchemy.orm import sessionmaker, scoped_session
# 模型类需要使用的模块
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, Integer, ForeignKey
# 数据操作的模块
from sqlalchemy import distinct, and_, or_
# 执行原生SQL的模块
from sqlalchemy import text # 1、pymsql创建引擎连接
# mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
engine = create_engine("mysql+pymysql://root:123456@192.168.3.109:3306/test", encoding="utf-8", echo=True) # 2、创建一个连接会话对象;需要指定是和哪个数据库引擎之间的会话
Session = sessionmaker(bind=engine)
session = Session() # 如果在创建会话的时候没有指定数据库引擎,可以通过如下的方式完成引擎绑定操作
# Session = sessionmaker()
# Session.configure(bind=engine)
# session = Session() # 安全session
# Session = scoped_session(sessionmaker(bind=engine))
# session = Session() # 3、模型类
# 创建基础类
BaseModel = declarative_base() # 创建模型类
class User(BaseModel):
# 定义表名
__tabelname__ = "tbl_user" # 创建字段类型
id = Column(Integer, primary_key=True)
name = Column(String(50))
age = Column(Integer) class Author(BaseModel):
__tablename__ = "tbl_author" id = Column(Integer, primary_key=True)
name = Column(String(50)) class Book(BaseModel):
__tablename__ = "tbl_book" id = Column(Integer, primary_key=True)
book_name = Column(String(50))
# ForeignKey 定义外键,需要导入
author_id = Column(Integer, ForeignKey("tbl_author.id")) # 删除所有模型类创建的表格(慎用)
# BaseModel.metadata.drop_all(engine)
# 创建所有模型类的表格,有则不创建
BaseModel.metadata.create_all(engine) # 4、数据操作
# 增
user1 = User(name="张三", age=18)
user2 = User(name="李四", age=19)
user3 = User(name="王五", age=20)
# 将单个对象加入到会话对象中
session.add(user1)
# 将多个对象加入到会话对象中
session.add_all([user2, user3])
# 提交数据
session.commit() # 返回User对象所有字段的所有信息,返回结果为对象列表
session.query(User) # 指定排序查询
session.query(User).order_by(User.id) # 升序查询
session.query(User).order_by(-User.id) # 降序查询
session.query(User).order_by(-User.id, User.name) # 多条件排序查询 # 返回User对象字段为id和name的所有信息,返回结果为元组列表
session.query(User.id, User.name) # 为字段取别名
session.query(User.id, User.name.label("n"))
# 对应SQL语句:SELECT tbl_user.id AS tbl_user_id, tbl_user.name AS n FROM tbl_user # 分组查询
session.query(User.name).group_by(User.name) # 查询常用聚合函数
from sqlalchemy.sql import func
session.query(func.max(User.age), # 最大
func.min(User.age), # 最小
func.sum(User.age), # 求和
func.avg(User.age), # 平均
func.count(User.age) # 统计
) # 去重查询
session.query(distinct(User.name)) # 使用limit()+offset()切片分页
# limit()限制返回条数
# offset()偏移
ret = session.query(User).limit(3).offset(2).all() # 返回第2条以后的3条数据,即第3至第5条数据
print(ret) # 使用slice()切片分页
ret = session.query(User).slice(2, 5).all() # 返回第3至第5条数据
print(ret) # 使用python列表切片分页
ret = session.query(User).all()[2:5] # 返回第3至第5条数据
print(ret) # 等于
session.query(User).filter(User.name == "李四")
# 不等于
session.query(User).filter(User.name != "李四") # 用户名包含“张”
session.query(User).filter(User.name.like("%张%"))
# 用户名不包含“张”
session.query(User).filter(User.name.notlike('%张%')) # in
session.query(User).filter(User.id.in_([1, 2, 4]))
# not in
session.query(User).filter(~User.id.in_([1, 2, 4])) # 空值
session.query(User).filter(User.name == None)
session.query(User).filter(User.name.is_(None)) # 非空
session.query(User).filter(User.name != None)
session.query(User).filter(User.name.isnot(None)) # 并且
session.query(User).filter(User.name == '张三').filter(User.age == 18)
session.query(User).filter(User.name == '张三', User.age == 18)
session.query(User).filter(and_(User.name == '张三', User.age == 18)) # 或者
session.query(User).filter(or_(User.name == '张三', User.name == '李四')) # 多表查询
session.query(Author.name, Book.book_name).filter(Author.id == Book.author_id)
# 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_author, tbl_book WHERE tbl_author.id = tbl_book.author_id # 内联查询join
session.query(Author.name, Book.book_name).join(Author, Author.id == Book.author_id)
# 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_book INNER JOIN tbl_author ON tbl_author.id = tbl_book.author_id # 左联查询outerjoin。没有右联查询
session.query(Author.name, Book.book_name).outerjoin(Author, Author.id == Book.author_id)
# 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_book LEFT OUTER JOIN tbl_author ON tbl_author.id = tbl_book.author_id # 并集查询
author_name = session.query(Author.name)
book_name = session.query(Book.book_name)
author_name.union(book_name)
# 对应SQL:SELECT anon_1.c_name FROM
# (SELECT tbl_author.name as c_name FROM tbl_author UNION SELECT tbl_book.book_name as c_name FROM tbl_book) AS anon_1 # all()返回所有的数据
session.query(User).all() # first()返回查询到的第一个结果,如果没有查询到结果,返回None。
session.query(User).first() # one()如果只能查询到一个结果,返回它,否则抛出异常。
session.query(User).filter(User.id == 2).one() # one_or_none()比起one()来,区别只是查询不到任何结果时不再抛出异常而是返回None。
session.query(User).filter(User.id == 2).one_or_none() # scalar()这个方法与.one_or_none()的效果一样。
session.query(User).filter(User.id == 2).scalar() # get()这是个比较特殊的方法。它用于根据主键来返回查询结果,因此它有个参数就是要查询的对象的主键。如果没有该主键的结果返回None,否则返回这个结果。
session.query(User).get(2) # update()更新数据
session.query(User).filter(User.id == 2).update({"name": "李四改"})
session.query(User).filter(User.id >= 4).update({"age": 88})
session.commit() # delete()删除数据
session.query(User).filter(User.id == 2).delete()
session.query(User).filter(User.id >= 4).delete()
session.commit() # 执行原生SQL
session.query(User).from_statement(text('select * from tbl_user where name=:name and age=:age')).params(name='李四', age=19)
session.query(User).from_statement(text('update tbl_user set name=:name where id=:id')).params(name='赵六', id=1)
session.commit()
原文参考:https://blog.csdn.net/u012089823/article/details/94650310
SQLAlchemy(十)的更多相关文章
- 我的python开发目录模块连接
一.python语言 二.HTML 三.css 四.javascript 五.DOM 六.jquery 七.AJAX 八.WEB前端插件 九.自定义WEB框架 十.WEB框架之tornado 十一.M ...
- Python开发【十二章】:ORM sqlalchemy
一.对象映射关系(ORM) orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却 ...
- 循序渐进Python3(十)-- 2 -- SqlAlchemy
ORM 对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类 ...
- 循序渐进Python3(十)-- 3 -- SqlAlchemy
使用sqlalchemy 创建外键关联 ), ), ) host_user = Column(String(), ), ), ]).first()for item in works.workinfo: ...
- python【第十二篇下】操作MySQL数据库以及ORM之 sqlalchemy
内容一览: 1.Python操作MySQL数据库 2.ORM sqlalchemy学习 1.Python操作MySQL数据库 2. ORM sqlachemy 2.1 ORM简介 对象关系映射(英语: ...
- python运维开发(十二)----rabbitMQ、pymysql、SQLAlchemy
内容目录: rabbitMQ python操作mysql,pymysql模块 Python ORM框架,SQLAchemy模块 Paramiko 其他with上下文切换 rabbitMQ Rabbit ...
- python第六十六天--sqlalchemy
#!usr/bin/env python #-*-coding:utf-8-*- # Author calmyan #python #2017/7/6 21:29 #__author__='Admin ...
- python(十二)下:ORM框架SQLAlchemy使用学习
此出处:http://blog.csdn.net/fgf00/article/details/52949973 本节内容 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 ...
- 第二百八十九节,MySQL数据库-ORM之sqlalchemy模块操作数据库
MySQL数据库-ORM之sqlalchemy模块操作数据库 sqlalchemy第三方模块 sqlalchemysqlalchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API ...
- 六十 数据库访问 使用SQLAlchemy
数据库表是一个二维表,包含多行多列.把一个表的内容用Python的数据结构表示出来的话,可以用一个list表示多行,list的每一个元素是tuple,表示一行记录,比如,包含id和name的user表 ...
随机推荐
- linux 磁盘满了,vim 编辑文件时无法保存
早上来发现 redis 不能用,报 MISCONF Redis is configured to save RDB snapshots, but it is currently not able to ...
- 【简】题解 P5283 [十二省联考2019]异或粽子
传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制 ...
- 【简】题解 P4297 [NOI2006]网络收费
传送门:P4297 [NOI2006]网络收费 题目大意: 给定一棵满二叉树,每个叶节点有一个状态(0,1),任选两个叶节点,如果这两个叶节点状态相同但他们的LCA所管辖的子树中的与他们状态相同的叶节 ...
- 基于Kubernetes的hpa实现pod实例数量的自动伸缩
Pod 是在 Kubernetes 体系中,承载用户业务负载的一种资源.Pod 们运行的好坏,是用户们最为关心的事情.在业务流量高峰时,手动快速扩展 Pod 的实例数量,算是玩转 Kubernetes ...
- C#编程概述(摘抄)
C#编程概述 一个简单的C#程序 标识符 标识符是一种字符串,用来命名变量.方法.参数和许多后面将要阐述的其他程序结构. 关键字 所有C#关键字都由小写字母组成,但是.NET类型名使用Pascal大小 ...
- Cyber Apocalypse 2021 pwn write up
Controller 考点是整数溢出和scanf函数的引发的栈溢出漏洞,泄露libc地址将返回地址覆盖成one_gadgets拿到shell. 1 from pwn import * 2 3 p = ...
- .net core使用EF core连接mssqlserver数据库
一,打开控制台二,输入以下代码1.Install-Package Microsoft.EntityFrameworkCore 2.Install-Package Microsoft.EntityFra ...
- HSPICE 电平触发D触发器仿真
一. HSPICE的基本操作过程 打开HSPICE程序,通过OPEN打开编写好的网表文件. 按下SIMULATE进行网表文件的仿真. 按下AVANWAVES查看波形图(仿真结果). 二. 网表文件结构 ...
- CF1199B Water Lily 题解
Content 有一朵长在水中的莲花,其茎秆部分露出水面的高度为 \(h\).有人将它往右边拽了 \(l\) 米,使得整个茎秆部分都浸在水中.求池水的深度. 数据范围:\(1\leqslant h&l ...
- AcWing429. 奖学金
题目: 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金. 期末,每个学生都有3门课的成绩:语文.数学.英语. 先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从 ...