当前位置: 首页 > article >正文

SqlServer整库迁移至Oracle


import pandas as pd
from sqlalchemy import create_engine, text
import cx_Oracle
from sqlalchemy.exc import DatabaseError
import traceback# SQL Server 配置
sql_server_conn_str = 'mssql+pyodbc://用户名:密码@数据库地址:端口/库名?driver=ODBC+Driver+11+for+SQL+Server'
sql_server_engine = create_engine(sql_server_conn_str)# Oracle 配置
oracle_conn_str = 'oracle+cx_oracle://用户名:密码@数据库地址:端口/库名'
oracle_engine = create_engine(oracle_conn_str,connect_args={"encoding": "UTF-8", "nencoding": "UTF-8"})def get_sqlserver_columns(table_name):"""获取SQL Server表的列定义"""with sql_server_engine.connect() as conn:columns = conn.execute(text(f"""SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTHFROM INFORMATION_SCHEMA.COLUMNSWHERE TABLE_NAME = '{table_name}'""")).fetchall()return columnsdef get_numeric_columns(table_name):"""获取需要转换为整数的列(NUMBER类型)"""with sql_server_engine.connect() as conn:result = conn.execute(text(f"""SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{table_name}'AND DATA_TYPE IN ('int', 'smallint', 'tinyint', 'bigint')"""))return [row.COLUMN_NAME for row in result]def map_oracle_type(sqlserver_type, max_length):"""SQL Server到Oracle类型映射"""sqlserver_type = sqlserver_type.lower()if max_length and max_length < 1:max_length = Nonetype_map = {'varchar': lambda: 'CLOB' if max_length is None else f'VARCHAR2({min(max_length, 4000)})','nvarchar': lambda: 'NCLOB' if max_length is None else f'NVARCHAR2({min(max_length, 2000)})','text': 'CLOB','char': lambda: f'CHAR({max_length})' if max_length else 'CHAR(1)','nchar': lambda: f'NCHAR({max_length})' if max_length else 'NCHAR(1)','int': 'NUMBER(10)','bigint': 'NUMBER(19)','smallint': 'NUMBER(5)','tinyint': 'NUMBER(3)','decimal': 'NUMBER','numeric': 'NUMBER','float': 'BINARY_DOUBLE','real': 'BINARY_FLOAT','datetime': 'TIMESTAMP(6)','datetime2': 'TIMESTAMP(6)','date': 'DATE','time': 'TIMESTAMP(6)','bit': 'NUMBER(1)'}if sqlserver_type in type_map:return type_map[sqlserver_type]() if callable(type_map[sqlserver_type]) else type_map[sqlserver_type]return 'CLOB'def migrate_table(table_name):try:oracle_table_name = table_name.upper()columns_info = get_sqlserver_columns(table_name)numeric_cols = get_numeric_columns(table_name)  # 获取需要转换的列# 构建Oracle表结构columns_with_types = [f'"{col.COLUMN_NAME}" {map_oracle_type(col.DATA_TYPE, col.CHARACTER_MAXIMUM_LENGTH)}'for col in columns_info]with oracle_engine.connect() as conn:if conn.execute(text("SELECT 1 FROM user_tables WHERE table_name = :name"),{'name': oracle_table_name}).scalar():print(f"删除旧表 {oracle_table_name}...")conn.execute(text(f'DROP TABLE "{oracle_table_name}" PURGE'))conn.commit()create_sql = f'CREATE TABLE "{oracle_table_name}" ({", ".join(columns_with_types)})'print(f"\n[DEBUG] 建表SQL:\n{create_sql}")conn.execute(text(create_sql))conn.commit()chunks = pd.read_sql_table(table_name,sql_server_engine,chunksize=10000)for chunk_idx, chunk_df in enumerate(chunks):# 空数据直接跳过if len(chunk_df) == 0:print(f"跳过空数据批次:{chunk_idx + 1}")continue# 空值处理chunk_df = chunk_df.where(pd.notnull(chunk_df), None)# 动态转换数值列for col in numeric_cols:if col in chunk_df.columns:chunk_df[col] = chunk_df[col].fillna(0).astype('int64')# 日期类型转换datetime_cols = [col for col in chunk_df.columnsif pd.api.types.is_datetime64_any_dtype(chunk_df[col])]for col in datetime_cols:chunk_df[col] = chunk_df[col].dt.tz_localize(None)# 构建插入SQLcolumns = ', '.join([f'"{col}"' for col in chunk_df.columns])placeholders = ', '.join([f':{col}' for col in chunk_df.columns])insert_sql = text(f"""INSERT INTO "{oracle_table_name}" ({columns}) VALUES ({placeholders})""")try:conn.execute(insert_sql, chunk_df.to_dict(orient='records'))conn.commit()print(f"批次 {chunk_idx + 1}: 成功插入 {len(chunk_df)} 行")except DatabaseError as e:conn.rollback()print(f"插入失败: {str(e)}")print("问题数据样例:", chunk_df.iloc[0].to_dict())returnexcept Exception as e:print(f"严重错误: {str(e)}")traceback.print_exc()def migrate_database():with sql_server_engine.connect() as conn:tables = conn.execute(text("""SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'""")).fetchall()exclude_tables = ['表名']  # 要过滤的表for table in tables:table_name = table[0]# 跳过特定表(不区分大小写)if table_name.upper() in [t.upper() for t in exclude_tables]:print(f"\n{'=' * 30} 跳过表 {table_name} {'=' * 30}")continueprint(f"\n{'=' * 30} 迁移表 {table_name} {'=' * 30}")migrate_table(table_name)if __name__ == '__main__':# migrate_table('表名')  # 单表测试migrate_database()  # 全库迁移print("\n迁移完成")

上面代码主要是解决整库迁移过程中相关表的创建(备注:不同数据库之间数据类型的映射转换),还有读取原始数据的类型转换 和 分批插入优化。

注意事项:

Oracle

1.在pycharm搜索不到cx_Oracle的库,通过cmd的方式进入python安装环境的目录Scripts下,然后pip install cx_Oracle 进行导入。

2.配置 Oracle Instant Client

1).根据Oracle的版本和操作系统进行相应下载  

官方地址:Oracle Instant Client Downloads

2).配置环境变量

  • Windows:将解压路径添加到系统 Path 变量。

SqlServer

1.根据SqlServer的版本进行驱动下载安装

官方地址:Download ODBC Driver for SQL Server - ODBC Driver for SQL Server | Microsoft Learn

相关文章:

SqlServer整库迁移至Oracle

import pandas as pd from sqlalchemy import create_engine, text import cx_Oracle from sqlalchemy.exc import DatabaseError import traceback# SQL Server 配置 sql_server_conn_str mssqlpyodbc://用户名:密码数据库地址:端口/库名?driverODBCDriver11forSQLServer sq…...

通过 Docker Swarm 集群探究 Overlay 网络跨主机通信原理

什么是Overlay网络, 用于解决什么问题 ? Overlay网络通过在现有网络之上创建一个虚拟网络层, 解决不同主机的容器之间相互通信的问题 如果没有Overlay网络&#xff0c;实现跨主机的容器通信通常需要以下方法&#xff1a; 端口映射使用宿主机网络模式 这些方法牺牲了容器网络…...

HarmonyOS NEXT开发进阶(十四):HarmonyOS应用开发者基础认证试题集汇总及答案解析

文章目录 一、前言二、判断题&#xff08;134道&#xff09;三、单选题&#xff08;210道&#xff09;四、多选题&#xff08;123道&#xff09;五、拓展阅读 一、前言 鸿蒙原生技能学习阶段&#xff0c;通过官方认证的资格十分有必要&#xff0c;在项目实战前掌握基础开发理论…...

linux shell 删除空行(remove empty lines)

命令行 grep -v ^$ file sed /^$/d file 或 sed -n /./p file awk /./ {print} file 或 awk {if($0!" ") print} tr -s "n"vim交互 %s/^n//g...

MSVC编译遇到C2059、C2143、C2059、C2365、C2059等错误的解决方案

MSVC编译时&#xff0c;遇到如下错误&#xff1a; c:\program files (x86)\windows kits\10\include\10.0.18362.0\um\msxml.h(1842): error C2059: 语法错误:“常数” [D:\jenkins_home\workspace\xxx.vcxproj] c:\program files (x86)\windows kits\10\include\10.0.18362.0…...

AI重塑云基础设施,亚马逊云科技打造AI定制版IaaS“样板房”

AI正在彻底重塑云基础设施。 IDC最新《2025年IDC MarketScape&#xff1a;全球公有云基础设施即服务&#xff08;IaaS&#xff09;报告》显示&#xff0c;AI正在通过多种方式重塑云基础设施&#xff0c;公有云IaaS有望继续保持快速增长&#xff0c;预计2025年全球IaaS的整体规…...

Linux系统之systemctl管理服务及编译安装配置文件安装实现systemctl管理服务

目录 一.systemctl 管理服务 1.systemctl管理 2.设置服务卡机自启动或开机不启动 二.编译安装配置文件编写使得可以使用systemctl管理 1、编写配置文件原因 2、添加配置文件实现systemctl管理服务 一.systemctl 管理服务 1.systemctl管理 基本格式&#xff1a; systemc…...

【NLP 52、多模态相关知识】

生活应该是美好而温柔的&#xff0c;你也是 —— 25.4.1 一、模态 modalities 常见&#xff1a; 文本、图像、音频、视频、表格数据等 罕见&#xff1a; 3D模型、图数据、气味、神经信号等 二、多模态 1、Input and output are of different modalities (eg&#xff1a; tex…...

【树莓派Pico FreeRTOS】-软件定时器(Software Timers)

软件定时器(Software Timers) 文章目录 软件定时器(Software Timers)1、硬件准备2、软件准备3、FreeRTOS的软件定时器介绍3.1 触发一次定时器(Oneshort Timer)3.2 重复定时器RP2040 由 Raspberry Pi 设计,具有双核 Arm Cortex-M0+ 处理器和 264KB 内部 RAM,并支持高达 16MB 的…...

My first day in QT programming

My first QT code this->setWindowTitle("HelloWorld"); //设置窗口名称 this->resize(400, 300); //设置窗口大小 QPushButton* btn new QPushButton; //新建按钮组件 btn->setParent(this); //为按钮指定父对象 …...

MySQL分组的时候遇到ONLY_FULL_GROUP_BY报错和解决

一、ONLY_FULL_GROUP_BY 错误的根本原因 MySQL 5.7 及以上版本默认启用了 sql_modeonly_full_group_by 严格模式。该模式强制要求&#xff1a; SELECT 中的非聚合字段必须出现在 GROUP BY 子句中&#xff1b;所有非聚合字段需通过聚合函数&#xff08;如 MAX、MIN、SUM&#…...

Element Plus 常用组件

2025/4/1 向全栈工程师迈进&#xff01;&#xff01;&#xff01; 常见Element Plus组件的使用&#xff0c;其文章中“本次我使用到的按钮如下”是我自己做项目时候用到的&#xff0c;记录以加强记忆。阅读时可以跳过。 一、Button按钮 1.1基础按钮 在element plus中提供的按…...

2025年优化算法:真菌生长优化算法(Fungal Growth Optimizer,FGO)

真菌生长优化算法(Fungal Growth Optimizer&#xff0c;FGO) 是发表在中科院一区期刊“ARTIFICIAL INTELLIGENCE REVIEW”&#xff08;IF&#xff1a;6.7&#xff09;的2025年3月智能优化算法 01.引言 Fungal Growth Optimizer (FGO) 是一种基于真菌生长行为的元启发式优化算法…...

人工智能之数学基础:矩阵分解之LU分解

本文重点 LU分解是线性代数中一种重要的矩阵分解方法,它将一个方阵分解为一个下三角矩阵(L)和一个上三角矩阵(U)的乘积。这种分解方法在数值线性代数中有着广泛的应用,特别是在求解线性方程组、计算矩阵的行列式、求逆矩阵等方面。 LU分解的基本概念 设A是一个nn的方阵…...

阿里通义千问发布全模态开源大模型Qwen2.5-Omni-7B

Qwen2.5-Omni 是一个端到端的多模态模型&#xff0c;旨在感知多种模态&#xff0c;包括文本、图像、音频和视频&#xff0c;同时以流式方式生成文本和自然语音响应。汇聚各领域最先进的机器学习模型&#xff0c;提供模型探索体验、推理、训练、部署和应用的一站式服务。https:/…...

23 种设计模式中的解释器模式

给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;并定义一个解释器&#xff0c;这个解释器使用该表示来解释语言中的句子。 这种模式通常用于需要解释执行某种语言的场景&#xff0c;如正则表达式、SQL解析等。 解释器模式的核心组件。 抽象表达式&#xff08;Ab…...

AquaMoon and Chess_CodeForces - 1545B

由110变成011&#xff0c;由011变成110&#xff0c;“11”的组合和0可以交换位置 如果是1110 或者是 1110 的情况&#xff0c;红色的“11”与0换位置&#xff0c;变成1011&#xff0c;可以看成蓝色的“11”到了0的后面&#xff0c;蓝色“11”和0的相对位置改变了&#xff0c;而…...

软考-数据库系统工程师第四版pdf

软考-数据库系统工程师第四版pdf git中的文件相对没有那么清楚&#xff0c;网盘的有高清版 github下载 这里我给出仓库地址 链接: https://github.com/yaodada123/ruankao-pdf https://github.com/yaodada123/ruankao-pdf gitee下载 https://gitee.com/yao-hengchao/ruank…...

淘天集团Java开放岗暑期实习笔试(2025年4月2日)

摘要&#xff1a; 除3道笔试题外&#xff0c;还有10道单选、5道不定项、2道Java单选、1道Java不定项选择题&#xff0c;笔试时长100分组&#xff0c;整体难度很大。三道算法题本人全部没有AC&#xff08;惭愧&#xff09;&#xff0c;事后总结至此。 第一道算法题&#xff0c…...

关于 数据库 UNION 和 UNION ALL 的使用,以及 分库分表环境下多表数据组合后的排序和分页问题的解决方案 的详细说明,并以表格总结关键内容

以下是关于 数据库 UNION 和 UNION ALL 的使用&#xff0c;以及 分库分表环境下多表数据组合后的排序和分页问题的解决方案 的详细说明&#xff0c;并以表格总结关键内容&#xff1a; 1. UNION 和 UNION ALL 的核心区别 1.1 定义与语法 UNION 功能&#xff1a;合并两个或多个 …...

【接口重复请求】axios通过AbortController解决页面切换过快,接口重复请求问题

处理网络请求时&#xff0c;我们经常会遇到需要中途取消请求的情况&#xff0c;比如用户在两个tab之间反复横跳的场景&#xff0c;如果每个接口都从头请求到结束&#xff0c;那必然会造成很大的服务压力。 AbortController是一个Web API&#xff0c;它提供了一个信号对象&…...

论文阅读:基于增强通用深度图像水印的混合篡改定位技术 OmniGuard

一、论文信息 论文名称:OmniGuard: Hybrid Manipulation Localization via Augmented Versatile Deep Image Watermarking作者团队:北京大学发表会议:CVPR2025论文链接:https://arxiv.org/pdf/2412.01615二、动机与贡献 动机: 随着生成式 AI 的快速发展,其在图像编辑领…...

Flutter极速接入IM聊天功能并支持鸿蒙

Flutter极速接入IM聊天功能并支持鸿蒙 如果你们也是Flutter项目&#xff0c;想快速接入聊天&#xff0c;包括聊天的UI界面&#xff0c;强烈推荐这一家。因为我们已经完成了集成&#xff0c;使用非常稳定&#xff0c;集成也非常快捷方便。 而且&#xff0c;就在今天&#xff0c…...

深挖 DeepSeek 隐藏玩法·智能炼金术2.0版本

前引&#xff1a;屏幕前的你还在AI智能搜索框这样搜索吗&#xff1f;“这道题怎么写”“苹果为什么红”“怎么不被发现翘课” &#xff0c;。看到此篇文章的小伙伴们&#xff01;请准备好你的思维魔杖&#xff0c;开启【霍格沃茨模式】&#xff0c;看我如何更新秘密的【知识炼金…...

C语言数组知识点

一、数组的基本概念 1.定义 数组是相同数据类型元素的集合&#xff0c;通过连续内存存储&#xff0c;支持高效访问。 核心特点&#xff1a; 元素类型相同 内存连续分配 通过下标访问&#xff08;从 0 开始&#xff09; 2.分类 一维数组&#xff1a;线性结构&#xff08;如…...

【新手初学】SQL注入getshell

一、引入 木马介绍&#xff1a; 木马其实就是一段程序&#xff0c;这个程序运行到目标主机上时&#xff0c;主要可以对目标进行远程控制、盗取信息等功能&#xff0c;一般不会破坏目标主机&#xff0c;当然&#xff0c;这也看黑客是否想要搞破坏。 木马类型&#xff1a; 按照功…...

DAY 34 leetcode 349--哈希表.两个数组的交集

题号349 我尝试硬解失败 /*class Solution {public int[] intersection(int[] nums1, int[] nums2) {int n1nums1.length;int n2nums2.length;int sizeMath.min(n1,n2);int []arrnew int[size];int count0;for(int i0;i<n1;i){outerloop:for(int j0;j<n2;j){if(nums1[i…...

Qt常用宏定义判断大全

Qt 提供了一系列预定义宏用于判断 Qt 版本、操作系统平台、编译器特性等。这些宏在跨平台开发中非常有用。 1. Qt 版本判断宏 // 检查Qt版本 #if QT_VERSION > QT_VERSION_CHECK(5, 15, 0)// Qt 5.15.0及以上版本特有代码 #endif// 常用版本判断 #if QT_VERSION > QT_V…...

tsconfig.json:error TS6306: Referenced project ‘/tsconfig.node.json‘

这是TypeScript配置文件中的错误。具体有两个问题&#xff1a; 错误TS6306&#xff1a;引用的项目/tsconfig.node.json必须设置"composite": true错误TS6310&#xff1a;引用的项目tsconfig.node.json不能禁用emit 要解决这些问题&#xff0c;需要修改tsconfig.nod…...

14-SpringBoot3入门-MyBatis-Plus之CRUD

1、整合 13-SpringBoot3入门-整合MyBatis-Plus-CSDN博客 2、表 3、crud package com.sgu;import com.sgu.mapper.UserMapper; import com.sgu.pojo.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.spri…...