Python数据库操作模式

什么是ORM?
对象关系映射(Object-Relational Mapping,ORM)是一种编程技术,它允许开发者使用面向对象的方式来操作数据库。ORM库将数据库表映射为Python类,将表中的行映射为对象,将字段映射为对象的属性,将SQL查询映射为方法调用。这样,开发者可以使用Python代码来操作数据库,而不需要直接编写SQL语句。
为什么使用ORM?

  1. 提高开发效率:ORM可以减少编写SQL语句的时间,使开发者可以专注于业务逻辑。
  2. 提高代码可维护性:ORM代码通常更易于阅读和维护。
  3. 跨数据库支持:大多数ORM库支持多种数据库,可以轻松切换数据库而无需修改代码。
  4. 事务管理:ORM通常提供事务管理功能,简化事务处理。

常见的Python ORM库

  1. SQLAlchemy:功能强大且灵活,支持多种数据库,提供了ORM和SQL表达式语言。

  2. Django ORM:Django框架自带的ORM,简单易用,适合快速开发。

  3. Peewee:轻量级ORM,易于学习和使用。

  4. Tortoise ORM:支持异步操作的ORM,适合异步应用。

使用SQLAlchemy进行ORM操作

from contextlib import contextmanager

from sqlalchemy import create_engine, and_, update, select
from sqlalchemy.orm import sessionmaker, registry, relationship
from sqlalchemy import Column, Integer, String, Float, ForeignKey

# 创建一个映射注册表
mapperregistry = registry()

Base = mapperregistry.generatebase()


class Invoice(Base):
    tablename = 'invoice'
    id = Column(Integer, primarykey=True)
    ordersn = Column(String(50))
    # 其他字段...


class InvoiceInfo(Base):
    tablename = 'invoiceinfo'
    id = Column(Integer, primarykey=True)
    invoiceid = Column(Integer, ForeignKey('invoice.id'))
    recid = Column(Integer)
    name = Column(String(100))
    units = Column(String(50))
    class = Column('class', String(100))  # 修改为 class
    classcode = Column(String(50))
    taxrate = Column(Float)
    invoice = relationship("Invoice", backpopulates="invoiceinfo")


Invoice.invoiceinfo = relationship("InvoiceInfo", orderby=InvoiceInfo.id, backpopulates="invoice")


class MilitaryOrderGoods(Base):
    tablename = 'militaryordergoods'
    id = Column(Integer, primarykey=True)
    recid = Column(Integer)
    goodsid = Column(Integer)
    # 其他字段...


class Goods(Base):
    tablename = 'goods'
    id = Column(Integer, primarykey=True)
    goodsid = Column(Integer)
    invoicename = Column(String(100))
    unit = Column(String(50))
    classname = Column(String(100))
    classcode = Column(String(50))
    # 其他字段...


class TaxCategories(Base):
    tablename = 'taxcategories'
    classid = Column(Integer, primarykey=True)
    classname = Column(String(100))
    classcode = Column(String(50))
    taxrate = Column(Float)
    flag = Column(Integer)  # 假设 flag 是一个整数字段
    # 其他字段...


@contextmanager
def getdbsession():
    engine = createengine(
        'mysql+pymysql://test?charset=utf8')
    Session = sessionmaker(bind=engine)
    session = Session()
    try:
        yield session
        session.commit()
    except Exception as e:
        session.rollback()
        raise e
    finally:
        session.close()


def updateinvoicefields(ordersn, name=None, units=None, classname=None, taxrate=None):
    with getdbsession() as session:
        # 构造更新条件
        conditions = [Invoice.ordersn == ordersn]

        # 打印条件过滤结果
        print(f"Conditions: {conditions}")
        subquerytax = select(TaxCategories.classname, TaxCategories.classcode).where(
            TaxCategories.classname == classname,
            TaxCategories.flag == 1
        ).limit(1)
        result = session.execute(subquerytax).fetchone()

        if result:
            classnamevalue = result[0]
            classcodevalue = result[1]
            print('result-------------', result)
        else:
            print('No matching record found for classname and classcode.')
            return 0

        # 构造连接
        subquery = (
            select(
                InvoiceInfo.id,
                Goods.goodsid,
                Goods.invoicename,
                Goods.unit
            )
                .join(Invoice, Invoice.id == InvoiceInfo.invoiceid)
                .join(MilitaryOrderGoods, InvoiceInfo.recid == MilitaryOrderGoods.recid)
                .join(Goods, MilitaryOrderGoods.goodsid == Goods.goodsid)
                .filter(and(*conditions))
        )

        # 获取子查询结果
        results = session.execute(subquery).fetchall()
        print('results-------------', results)
        if not results:
            print("No records to update.")
            return 0
            # 构造更新字典
        updatevalues = {
            'class': classnamevalue,
            'name': name,
            'classcode': classcodevalue,
            'taxrate': taxrate
        }
        # 只有在 units 不为空时才添加到更新字段中
        if units and units.strip():
            updatevalues['units'] = units
        # 构造更新语句
        stmtinvoiceinfo = (
            update(InvoiceInfo)
                .where(InvoiceInfo.id.in([row[0] for row in results]))
                .values(**updatevalues
                        )
        )

        stmtgoods = (
            update(Goods)
                .where(Goods.goodsid.in([row[1] for row in results]))
                .values(
                invoicename=name,
                unit=units
            )
        )

        # 执行更新操作
        updatedcountinvoiceinfo = session.execute(stmtinvoiceinfo).rowcount
        updatedcountgoods = session.execute(stmtgoods).rowcount

        # 打印更新的记录数
        print(f"Updated Records Count in InvoiceInfo: {updatedcountinvoiceinfo}")
        print(f"Updated Records Count in Goods: {updatedcountgoods}")

        # 返回更新的行数
        return updatedcountinvoiceinfo + updatedcountgoods


# 调用示例
print(updateinvoicefields("20220110134064", name="测试事务回滚", units='', classname="日用杂品", taxrate=13))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946159.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RoboMIND:多体现基准 机器人操纵的智能规范数据

我们介绍了 RoboMIND,这是机器人操纵的多体现智能规范数据的基准,包括 4 个实施例、279 个不同任务和 61 个不同对象类别的 55k 真实世界演示轨迹。 工业机器人企业 埃斯顿自动化 | 埃夫特机器人 | 节卡机器人 | 珞石机器人 | 法奥机器人 | 非夕科技 | C…

【Spring MVC 核心机制】核心组件和工作流程解析

在 Web 应用开发中,处理用户请求的逻辑常常会涉及到路径匹配、请求分发、视图渲染等多个环节。Spring MVC 作为一款强大的 Web 框架,将这些复杂的操作高度抽象化,通过组件协作简化了开发者的工作。 无论是处理表单请求、生成动态页面&#x…

郑州时空-TMS运输管理系统 GetDataBase 信息泄露漏洞复现

0x01 产品简介 郑州时空-TMS运输管理系统是一款专为物流运输企业设计的综合性管理软件,旨在提高运输效率、降低运输成本,并实现供应链的协同运作。系统基于现代计算机技术和物流管理方法,结合了郑州时空公司的专业经验和技术优势,为物流运输企业提供了一套高效、智能的运输…

电子应用设计方案81:智能AI冲奶瓶系统设计

智能 AI 冲奶瓶系统设计 一、引言 智能 AI 冲奶瓶系统旨在为父母或照顾者提供便捷、准确和卫生的冲奶服务,特别是在夜间或忙碌时,减轻负担并确保婴儿获得适宜的营养。 二、系统概述 1. 系统目标 - 精确调配奶粉和水的比例,满足不同年龄段婴…

Three.js教程004:坐标辅助器与轨道控制器

文章目录 坐标辅助器与轨道控制器实现效果添加坐标辅助器添加轨道控制器完整代码完整代码下载坐标辅助器与轨道控制器 实现效果 添加坐标辅助器 创建坐标辅助器: const axesHelper = new Three.AxesHelper(5);添加到场景中: scene.

Mesh网格数据结构2-半边结构

文章目录 1.Edge-based data Structure2.HalfEdge-Based Data Structure3. Directed-edge data structure 本文将详细介绍半边结构(Halfedge-based data),以及Face-based data,Edge-based data, Directed-edge data structure. 上…

CSS---实现盒元素div内input/textarea的focus状态时给父元素加属性!

注意兼容性,低版本浏览器无效 要实现当 textarea 文本框获得焦点时,自动给其父元素添加类名或样式,您可以使用 CSS 的 :focus-within 伪类选择器。这个选择器会在元素本身或其任何子元素获得焦点时应用样式。 示例代码 假设您有以下 HTML 结…

天天跳绳(???)

广东省人民政府门户网站 https://www.gd.gov.cn/zwgk/zdlyxxgkzl/whjg/content/post... 二沙岛变身智能“运动岛” - 广东省人民政府门户网站 2020年10月20日  广州二沙岛,犹如一颗璀璨明珠点缀在珠江之心,自然风光旖旎,功能分区清 … 公共…

七、Vue 监听属性

文章目录 一、简介二、基本语法简单监听深度监听 三、与计算属性的区别计算属性(computed)的特点监听属性和计算属性的不同应用场景 四、在组件中的应用组件内监听属性父子组件通信中的监听属性 五、注意事项异步操作不要过度使用 一、简介 在 Vue.js 中…

视频流媒体解决方案:Liveweb国标GB28181视频监控汇聚平台

视频监控国标平台指的是基于GB/T 28181协议的视频联网平台,可以对接各种符合国标GB/T 28181协议的视频平台、NVR录像机、网络监控摄像头、执法记录仪、应急布控球、移动单兵、无人机等设备。通过国标平台的联网,方便管理分布在不同地点的视频监控和其他视…

Canoe 新建工程和通道连接

文章目录 新建工程硬件通道Vector 硬件驱动Hardware 配置1、通道数量配置2、通道映射3、配置通道波特率 新建工程 新建一个具有一个CAN通道的工程 Ctrl S 保存 硬件通道 以 Vector 1640 为例: Vector 1640通过 USB 和电脑连接后,观察指示灯&#xff…

安卓开发使用Gemini高效AI开发-Android Studio 中使用Gemini

Gemini 是Android Studio最新版本中内嵌的AI工具,它可以通过代码补全、解释代码、提供改进建议、错误分析等方式帮助开发者提高编码效率。当然,与目前大多数AI工具一样,Gemini有时可能会"非常自信"地提供不准确、错误的信息&#x…

从0开始的docker镜像制作-ubuntu22.04

从0开始的docker镜像制作-ubuntu22.04 一、拉取基础ubuntu22.04镜像二、进入拉取的docker镜像中,下载自己需要的安装包三、安装需要的系统软件四、打包现有镜像为一个新的镜像五、推送打包的镜像到私有docker服务器1.编辑docker文件,使其允许http传输和对…

软件测试——面试八股文(入门篇)

今天给大家分享软件测试面试题入门篇,看看大家能答对几题 一、 请你说一说测试用例的边界 参考回答: 边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。通常边界值分析法是作为对等价类划分法的补充,这种情况下&#xff…

面试场景题系列:设计指标监控和告警系统

在本文中,我们将探讨可扩展的指标监控和告警系统的设计。理解基础设施的状况对维持其可用性和可靠性至关重要。 图-1展示了一些市面上最流行的商用和开源的指标监控和告警服务。 图-1 1.场景边界界定 为了便于展开设计以及考虑通用性,监控和告警需求如…

Spring实现输出带动态标签的日志

版权说明: 本文由博主keep丶原创,转载请保留此块内容在文首。 原文地址: https://blog.csdn.net/qq_38688267/article/details/144851857 文章目录 背景底层原理实现方案Tag缓存实现封装注解通过AOP实现日志缓存封装行为参数通用方法实现手动…

1月第一讲:WxPython跨平台开发框架之前后端结合实现附件信息的上传及管理

1、功能描述和界面 前端(wxPython GUI): 提供文件选择、显示文件列表的界面。支持上传、删除和下载附件。展示上传状态和附件信息(如文件名、大小、上传时间)。后端(REST API 服务)&#xff1a…

微服务SpringCloud分布式事务之Seata

视频教程:https://www.bilibili.com/video/BV16P63Y3ESq 效果演示 准备的微服务项目调用的链路如下: 文字描述: gateway模块接收到请求,并发送到order订单模块order订单模块接收到请求,新增一个订单数据后发送一个…

Solon 加入 GitCode:助力国产 Java 应用开发新飞跃

在当今数字化快速发展的时代,Java 应用开发框架不断演进,开发者们始终在寻找更快、更小、更简单的解决方案。近期,Solon 正式加入 GitCode,为广大 Java 开发者带来全新的开发体验,尤其是在国产应用开发进程中&#xff…

[实用指南]如何将视频从iPhone传输到iPad

概括 将视频从 iPhone 传输到 iPad 时遇到问题?您可能知道一种方法,但不知道如何操作。此外,您要传输的视频越大,完成任务就越困难。那么如何将视频从 iPhone 传输到 iPad,特别是当您需要发送大视频文件时&#xff1f…