SQLAlchemy

SQLAlchemy


一、 什么是SQLAlchemy?

SQLAlchemy是Python一款非常强大的ORM软件

对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。


二、 怎么用?

1. 连接准备
  • 建立连接
from sqlalchemy import create_engine
engine_name = create_engine('mysql://root:@localhost:3306/webpy?                                charset=utf8',echo=True)

我们都知道,与数据库进行交互,首先就需要建立连接。create_engine函数返回一个engine对象,第一个参数标明了与哪个数据库建立连接,格式为数据库类型://用户名:密码(没有密码则为空,不填)@数据库主机地址/数据库名?编码,第二个参数echo默认为False,置为True后控制台会输出一些sql信息。

  • 创建会话
from sqlalchemy.orm import sessionmaker
session_name = sessionmaker(bind=engine_name)

session = session_name() # 实例化session

ORM通过session与数据库进行会话。一般而言,当第一次载入时(也就是建立连接的同时)会创建一个session类,这个session类为新的session对象提供服务。如果需要和数据库建立连接,只需实例化一个session。

虽然我们已经与数据库engine相关联,但是没有打开任何连接,当它第一次被使用时,就会从engine的一个连接池中检索是否存在连接,如果存在,便会保持连接直到我们提交所有更改或者关闭session对象。

2. 增删改查
建表
from sqlalchemy import Column,Integer,String

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

首先,我们要为数据库建表,ORM的好处就是通过描述对象与数据库的某张表直接映射。上述代码中,我们在项目里定义了User类,与数据库中的user表相对应,表中有整数类型、自增的主键id,有 不允许为空值、字符串类型的name列。

def add(cls, name):
    user = cls(name)     # 创建新的User对象
    session.add(user)    # 将对象加入数据库中
    session.commit()     # 提交更改

我们在User类中定义函数add()实现向数据库增加数据的功能。其步骤为:根据参数构造对象、将对象加入数据库、提交修改。

def delete_by_id(cls, id):
    user = session.query(cls).filter(cls.id==id)   # 查询
    if user:
        session.delete(user)  # 删除数据  
        session.commit()      # 提交更改

我们在User类中定义函数delete_by_id()实现根据用户id从数据库删除数据的功能。
忘掉这个delete(手动微笑)

def update(cls, id, update_values):
    row_count = session.query(cls).filter(id==id).
                update(values=update_values)
    session.commit()
    return row_count > 0

我们在User类中定义函数update()实现根据用户id从数据库修改数据的功能。

# 官方文档示例
from sqlalchemy import update

stmt = users.update().where(users.d==5).values(name='user #5')

# 函数原型
sqlalchemy.sql.expression.update(table, whereclause=None, values=
                                None, inline=False, bind=None, 
                                prefixes=None, returning=None, 
                                return_defaults=False, 
                                preserve_parameter_order=False, 
                                **dialect_kw)

查找是重中之重,设计数据库的大多数操作都与查询有关,即使是删除和更新也免不了查询操作。

  • 查询函数
func_nameparam
query(*entities, **kwargs)query(classname) or query(classname.column1,classname.column2) or query(func.max())

query方法会创建一个查询对象,根据参数获取相应的列。query()返回KeyedTuple类型的一个元组或多个元组组成的列表,元组格式为:<User(name='ed',fullname='Ed Jones', password='f8s7ccs')>ed,实际上为User('ed','EdJones','f8s7ccs'),而name,fullname,password为每个数据对应的标签。可以把它当作一个python类来操作。

print(User.name)
>>>'ed'
print(User.fullname)
>>>'Ed Jones'
  • 过滤器函数
func_nameparamdescribe
filter(*criterion)filter(classname.column==’xxxxxx’)过滤器,使用关键字变量过滤查询结果
filter_by(**kwargs)filter_by(column==’xxxxxx’)过滤器,使用关键字变量过滤查询结果

filter与filter_by都是帮助过滤查询结果的函数,但它们有一些不同。

filter用classname.column,支持运算符、and、or作为参数。

filter_by不必加上classname,不支持运算符、and、or做参数,因为参数为**kwargs支持组合查询。

filter().filter()
filter(and_(User.name =='ed',User.fullname =='Ed Jones'))
filter(or_(User.name =='ed', User.name =='wendy'))
filter(MyClass.name == 'some name', MyClass.id > 5)
filter(classname.column.like('%ed%'))
filter(classname.column.in_([,,]))

filter_by(column1=='xxx', column2=='xxx)
  • 返回结果处理函数
func_nameparamdescribe
all()返回keyedTuple元组的列表
first()返回查询结果的第一个
one()获取所有行,若查询不到or查询到多个对象or查询到一个对象但重复记录,抛出异常
scalar()在one()的基础上获得该行的第一列
order_by()order_by(classname.column)依据某列或某几列对查询结果按字典序排序
label()为某一列起别名
# 返回一个列表
session.query(User).filter_by(name=='fancy').all()   
# 返回查询到的第一个对象
session.query(User).filter_by(name=='fancy').first() 
# 只获得一条数据,如果没有获得 or 获得多条 则抛出异常
session.query(User).filter_by(name=='fancy').one() 
# 基于one()的基础,获得第一列的数据
session.query(User).filter_by(name=='fancy').scalar() 
  • 连表查询

    连表查询有两种方式,一种是通过filter,一种是通过join。

# 通过 query 与 filter 进行连表查询
session.query(User, Address).filter(User.id==Address.user_id).\
        filter(Address.city=='Peking')

# 通过join达到同样效果, 只有一个外键
session.query(User).join(Address).filter(Address.city=='Peking')

# 多个外键或者没有外键时,要给出明确条件
session.query(User).join(Address,User.id==Address.user_id).\
        filter(Address.city=='Peking')
session.query(User).join(Address,User.addresses).\
        filter(Address.city=='Peking')  
### RT-DETRv3 网络结构分析 RT-DETRv3 是一种基于 Transformer 的实时端到端目标检测算法,其核心在于通过引入分层密集正监督方法以及一系列创新性的训练策略,解决了传统 DETR 模型收敛慢和解码器训练不足的问题。以下是 RT-DETRv3 的主要网络结构特点: #### 1. **基于 CNN 的辅助分支** 为了增强编码器的特征表示能力,RT-DETRv3 引入了一个基于卷积神经网络 (CNN) 的辅助分支[^3]。这一分支提供了密集的监督信号,能够与原始解码器协同工作,从而提升整体性能。 ```python class AuxiliaryBranch(nn.Module): def __init__(self, in_channels, out_channels): super(AuxiliaryBranch, self).__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1) self.bn = nn.BatchNorm2d(out_channels) def forward(self, x): return F.relu(self.bn(self.conv(x))) ``` 此部分的设计灵感来源于传统的 CNN 架构,例如 YOLO 系列中的 CSPNet 和 PAN 结构[^2],这些技术被用来优化特征提取效率并减少计算开销。 --- #### 2. **自注意力扰动学习策略** 为解决解码器训练不足的问题,RT-DETRv3 提出了一种名为 *self-att 扰动* 的新学习策略。这种策略通过对多个查询组中阳性样本的标签分配进行多样化处理,有效增加了阳例的数量,进而提高了模型的学习能力和泛化性能。 具体实现方式是在训练过程中动态调整注意力权重分布,确保更多的高质量查询可以与真实标注 (Ground Truth) 进行匹配。 --- #### 3. **共享权重解编码器分支** 除了上述改进外,RT-DETRv3 还引入了一个共享权重的解编码器分支,专门用于提供密集的正向监督信号。这一设计不仅简化了模型架构,还显著降低了参数量和推理时间,使其更适合实时应用需求。 ```python class SharedDecoderEncoder(nn.Module): def __init__(self, d_model, nhead, num_layers): super(SharedDecoderEncoder, self).__init__() decoder_layer = nn.TransformerDecoderLayer(d_model=d_model, nhead=nhead) self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=num_layers) def forward(self, tgt, memory): return self.decoder(tgt=tgt, memory=memory) ``` 通过这种方式,RT-DETRv3 实现了高效的目标检测流程,在保持高精度的同时大幅缩短了推理延迟。 --- #### 4. **与其他模型的关系** 值得一提的是,RT-DETRv3 并未完全抛弃经典的 CNN 技术,而是将其与 Transformer 结合起来形成混合架构[^4]。例如,它采用了 YOLO 系列中的 RepNCSP 模块替代冗余的多尺度自注意力层,从而减少了不必要的计算负担。 此外,RT-DETRv3 还借鉴了 DETR 的一对一匹配策略,并在此基础上进行了优化,进一步提升了小目标检测的能力。 --- ### 总结 综上所述,RT-DETRv3 的网络结构主要包括以下几个关键组件:基于 CNN 的辅助分支、自注意力扰动学习策略、共享权重解编码器分支以及混合编码器设计。这些技术创新共同推动了实时目标检测领域的发展,使其在复杂场景下的表现更加出色。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值