达梦数据库-学习-46-sqlalchemy_dm+dmPython安装与示例

目录

一、环境信息

二、说点什么

三、下载链接

四、安装

1、Python3安装

2、环境变量配置

(1)配置

(2)生效

3、升级

4、SQLAlchemy安装

5、dmPython源码编译安装

(1)切换目录

(2)编译安装

6、sqlalchemy_dm源码编译安装

(1)切换目录

(2)编译安装

五、Demo

1、源码

2、运行

3、验证


一、环境信息

|------|--------------------------------------------------------------------------------------------------------------------|
| 名称 | 值 |
| CPU | 12th Gen Intel(R) Core(TM) i7-12700H |
| 操作系统 | CentOS Linux release 7.9.2009 (Core) |
| 内存 | 7G |
| 逻辑核数 | 8 |
| DM版本 | DM Database Server 64 V8 DB Version: 0x7000d 03134284368-20250917-293539-20149 Msg Version: 44 Gsu level(5) cnt: 0 |

二、说点什么

最近经常有客户使用sqlalchemy来操作达梦数据库出现问题,问题排查与解决的同时,也不由的感叹一下,sqlalchemy真的很便捷,python很适合快捷开发,入门比较友好,未入门者来说点什么。

三、下载链接

有的小伙伴想使用非源码编译安装,可以参考如下链接:

|----|--------------------------------------------------------------------------------------------------------------------------------------|
| 编号 | 链接 |
| 1 | 达梦数据库-学习-36-API驱动下载汇总 |

四、安装

1、Python3安装

|----|--------------------------------------------------------------------------------------------------------------------|
| 编号 | 链接 |
| 1 | Linux-学习-06-Python3安装与卸载 |

2、环境变量配置

(1)配置

/etc/profile添加如下内容:

bash 复制代码
export DM_HOME="/opt/Dm8"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$DM_HOME/bin"

(2)生效

bash 复制代码
. /etc/profile

3、升级

bash 复制代码
pip3 install --upgrade pip setuptools wheel

4、SQLAlchemy安装

bash 复制代码
pip3 install SQLAlchemy==1.4.48

5、dmPython源码编译安装

(1)切换目录

bash 复制代码
cd /opt/Dm8/drivers/python/dmPython

安装实际路径来。

(2)编译安装

bash 复制代码
python3 setup.py install

6、sqlalchemy_dm源码编译安装

(1)切换目录

bash 复制代码
cd /opt/Dm8/drivers/python/sqlalchemy1.4.6

安装实际路径来。

(2)编译安装

bash 复制代码
python3 setup.py install

五、Demo

1、源码

python 复制代码
#encoding:utf-8
from sqlalchemy import create_engine, Column, Integer, String, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
import time
import faulthandler
import os
import signal

faulthandler.enable(file=open('Core.log', 'w'))

def my_handler(signum, frame):
    with open('my_handler.log', 'a') as f:
        f.write('My handler caught signal : %d\n' % (signum))

# 创建基类
Base = declarative_base()

# 定义数据模型 - 学生表
class Student(Base):
    __tablename__ = 'students'
    
    id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable=False)
    student_id = Column(String(20), unique=True, nullable=False)  # 学号
    math_score = Column(Float, default=0.0)
    english_score = Column(Float, default=0.0)
    total_score = Column(Float, default=0.0)
    grade = Column(String(10), default='')  # 等级
    
    def __repr__(self):
        return "<Student(id={self.id}, name='{self.name}', total={self.total_score})>"

def main():
    LoadRows     = 1024
    new_students = []

    #signal.signal(signal.SIGSEGV, my_handler)
    
    # 创建SQLite内存数据库(生产环境请用文件数据库)
    engine = create_engine('dm://SYSDBA:qwer1234S@localhost:5236/',connect_args={'local_code':1,'connection_timeout':15})  # echo=True显示SQL语句

    #os.kill(os.getpid(), signal.SIGFPE)

    # 创建表
    Base.metadata.create_all(engine)
    
    # 创建会话工厂
    Session = sessionmaker(bind=engine)
    session = Session()
   
    try:
        print("=" * 50)
        print("示例1: 批量插入新学生记录")
        print("=" * 50)
        
        # 创建要批量插入的学生列表
        for i in range(LoadRows):
            new_students.append(Student(id=i, name='Sun', student_id=str(i), math_score=i, english_score=i+1))
        
        # 计算总分(演示在保存前可以预处理数据)
        for student in new_students:
            student.total_score = student.math_score + student.english_score
        
        # 批量保存 - 性能最高的方式
        start_time = time.time()
        session.bulk_save_objects(new_students)
        session.commit()
        elapsed_time = time.time() - start_time
        
        print("批量插入%d条记录完成,耗时: %4f 秒" % (len(new_students),elapsed_time))
        
        # 查询验证(注意:bulk_save_objects不会填充ID到对象)
        students_in_db = session.query(Student).all()
        
#        for s in students_in_db:
#            print("  ID:%d, 姓名:%s, 学号:%s, 总分:%f" % (s.id,s.name,s.student_id,s.total_score))
#        
#        print("\n" + "=" * 50)
#        print("示例2: 批量更新学生成绩和等级")
#        print("=" * 50)
#        
#        # 先查询出现有学生
#        existing_students = session.query(Student).all()
#        
#        # 模拟批量更新:调整分数并计算等级
#        for student in existing_students:
#            # 给每个学生加点分(模拟批处理)
#            student.math_score += 1.5
#            student.english_score += 1.0
#            student.total_score = student.math_score + student.english_score
#            
#            # 根据新总分计算等级
#            if student.total_score >= 180:
#                student.grade = 'A'
#            elif student.total_score >= 160:
#                student.grade = 'B'
#            elif student.total_score >= 140:
#                student.grade = 'C'
#            else:
#                student.grade = 'D'
#        
#        # 批量更新 - 使用相同的bulk_save_objects方法
#        session.bulk_save_objects(existing_students)
#        session.commit()
#        
#        print("批量更新完成!更新后的数据:")
#        updated_students = session.query(Student).order_by(Student.total_score.desc()).all()
#        for s in updated_students:
#            print("  姓名:{s.name:3} | 数学:{s.math_score:5.1f} | 英语:{s.english_score:5.1f} | 总分:{s.total_score:5.1f} | 等级:{s.grade}")
#        
#        final_students = session.query(Student).order_by(Student.id).all()
#        for s in final_students:
#            print("  ID:{s.id:2} | 姓名:{s.name:3} | 学号:{s.student_id} | 总分:{s.total_score:5.1f} | 等级:{s.grade}")
#        
#        # 注意:新插入的学生对象不会自动获取ID
#        # 如果需要ID,需要在commit后重新查询
#        print("\n注意:使用bulk_save_objects新插入的对象不会自动获取ID")
#        print("例如,孙八的ID在对象中仍然是: {mixed_operations[1].id if len(mixed_operations) > 1 else 'N/A'}")
#        
#        # 如果需要获取新插入的ID,可以使用return_defaults参数(但有性能代价)
#        print("\n" + "=" * 50)
#        print("示例4: 使用return_defaults获取新插入的ID")
#        print("=" * 50)
#        
#        # 创建新会话,演示return_defaults
#        session2 = Session()
#        
#        new_student_with_id = Student(
#            name='吴十', 
#            student_id='20230008', 
#            math_score=88.0, 
#            english_score=92.0, 
#            total_score=180.0
#        )
#        
#        # 使用return_defaults=True,这样有默认值(如自增ID)的列会被填充
#        # 注意:这会影响性能,只应用于确实需要立即获取ID的场景
#        session2.bulk_save_objects([new_student_with_id], return_defaults=True)
#        session2.commit()
#        
#        print("使用return_defaults后,新学生的ID: {new_student_with_id.id}")
#        
#        # 清理
#        session2.close()
        
    except Exception as e:
        session.rollback()
        print("发生错误: {e}")
        import traceback
        traceback.print_exc()
    finally:
        session.close()
        print("\n程序执行完毕!")

if __name__ == "__main__":
    main()

2、运行

bash 复制代码
[dmdba@lzl PythonScript]$ python3 DmSqlAlchemy.py 
==================================================
示例1: 批量插入新学生记录
==================================================
批量插入1024条记录完成,耗时: 0.195764 秒

程序执行完毕!

3、验证

bash 复制代码
SQL> SELECT * FROM STUDENTS LIMIT 10;

行号     ID          NAME STUDENT_ID MATH_SCORE                ENGLISH_SCORE             TOTAL_SCORE               GRADE
---------- ----------- ---- ---------- ------------------------- ------------------------- ------------------------- -----
1          0           Sun  0          0.000000000000000E+00     1.000000000000000E+00     1.000000000000000E+00     
2          1           Sun  1          1.000000000000000E+00     2.000000000000000E+00     3.000000000000000E+00     
3          2           Sun  2          2.000000000000000E+00     3.000000000000000E+00     5.000000000000000E+00     
4          3           Sun  3          3.000000000000000E+00     4.000000000000000E+00     7.000000000000000E+00     
5          4           Sun  4          4.000000000000000E+00     5.000000000000000E+00     9.000000000000000E+00     
6          5           Sun  5          5.000000000000000E+00     6.000000000000000E+00     1.100000000000000E+01     
7          6           Sun  6          6.000000000000000E+00     7.000000000000000E+00     1.300000000000000E+01     
8          7           Sun  7          7.000000000000000E+00     8.000000000000000E+00     1.500000000000000E+01     
9          8           Sun  8          8.000000000000000E+00     9.000000000000000E+00     1.700000000000000E+01     
10         9           Sun  9          9.000000000000000E+00     1.000000000000000E+01     1.900000000000000E+01     

10 rows got

已用时间: 3.286(毫秒). 执行号:15002.
相关推荐
sunxunyong3 小时前
CGroup配置
linux·运维·服务器
小吴编程之路3 小时前
MySQL 索引核心特性深度解析:从底层原理到实操应用
数据库·mysql
炽烈小老头3 小时前
【每天学习一点算法 2026/03/08】相交链表
学习·算法·链表
hy____1234 小时前
Linux_网络编程套接字
linux·运维·网络
~莫子4 小时前
MySQL集群技术
数据库·mysql
凤山老林4 小时前
SpringBoot 使用 H2 文本数据库构建轻量级应用
java·数据库·spring boot·后端
若风的雨4 小时前
【deepseek】 Linux 调度延时分析
linux
就不掉头发4 小时前
Linux与数据库进阶
数据库
与衫4 小时前
Gudu SQL Omni 技术深度解析
数据库·sql
小夏卷编程4 小时前
Ubuntu 20.04.4 宝塔 docker showdoc v3.2 更新到v3.7.3
运维·docker·容器