python批量跑plsql_python實現自動化報表(Oracle/plsql/Excel/多線程)

# -*- coding: utf-8 -*-

# Create time: 2019-10-16

# Update time: 2019-11-28

# Version: 1.0

# Version: 2.0 增加多線程/出錯自動重新運行模塊

# 導入模塊

import cx_Oracle

import os

import pandas as pd

import pandas.io.sql as sql

import time

import openpyxl

import xlwings as xw

import logging

import re

import threading

# 獲取工作目錄

sqlpath = os.getcwd() + '\\'? # 獲取當前文件夾目錄,若不正確則使用后面的代碼直接輸入 sqlpath = 'E:\\'

# 設置運行日志

logging.basicConfig(format='%(asctime)s - %(pathname)s] - %(levelname)s: %(message)s', level=logging.INFO, filename=sqlpath+'log.txt')

# 獲取系統日期(用于命名文件)

time_start=time.time()

date = time.strftime("%Y%m%d")

# 定義變量

name = '經營日報' # 模版名稱

print('開始運行: %s' %name)

# sql代碼文件名

sql1 = sqlpath + 'hangxian_ri.sql'

sql2 = sqlpath + 'hangxian_zhou.sql'

sql3 = sqlpath + 'hangxian_yue.sql'

# 定義空DataFrame(函數中要使用,必須要先定義)

result1 = pd.DataFrame()

result2 = pd.DataFrame()

result3 = pd.DataFrame()

# 定義可以讀取運行sql的函數

def read_run_write1(sql_name):

global result1 # 調用全局變量result1,使用global才能對全局變量進行修改

print('正在運行代碼: %s' %sql_name)

with open(sql_name,encoding='utf-8-sig',mode='r') as f: # 讀取oracle代碼,中文編碼utf-8-sig,

sql_list = f.read()

sql_list = re.sub(r'--.*', '', sql_list) # 去除注釋

connection = cx_Oracle.connect('賬號/密碼@IP地址/數據庫名稱')

code = sql_list.replace('\n', ' ').replace(';','') # 將換行符轉為空格,去除分號

for i in range(5): # 運行oracle代碼,若運行失敗則10秒自動重新運行

try:

result1 = sql.read_sql(code, connection) # 利用pd包的read_sql函數運行代碼,返回DataFrame類型的結果

break # 代碼運行成功則跳出循環

except:

print('代碼%s運行出錯,正在重新運行第%d次' %(sql_name,(i+1)))

time.sleep(10) # 代碼運行失敗則10秒后再重新運行

print('代碼運行完成: %s' %sql_name)

def read_run_write2(sql_name):

global result2

print('正在運行代碼: %s' %sql_name)

with open(sql_name,encoding='utf-8-sig',mode='r') as f:

sql_list = f.read()

sql_list = re.sub(r'--.*', '', sql_list) # 去除注釋

connection = cx_Oracle.connect('賬號/密碼@IP地址/數據庫名稱')

code = sql_list.replace('\n', ' ').replace(';','') # 將換行符轉為空格,去除分號

for i in range(5):

try:

result2 = sql.read_sql(code, connection)

break

except:

print('代碼%s運行出錯,正在重新運行第%d次' %(sql_name,(i+1)))

time.sleep(10)

print('代碼運行完成: %s' % sql_name)

def read_run_write3(sql_name):

global result3

print('正在運行代碼: %s' %sql_name)

with open(sql_name,encoding='utf-8-sig',mode='r') as f:

sql_list = f.read()

sql_list = re.sub(r'--.*', '', sql_list) # 去除注釋

connection = cx_Oracle.connect('賬號/密碼@IP地址/數據庫名稱')

code = sql_list.replace('\n', ' ').replace(';','') # 將換行符轉為空格,去除分號

for i in range(5):

try:

result3 = sql.read_sql(code, connection)

break

except:

print('代碼%s運行出錯,正在重新運行第%d次' %(sql_name,(i+1)))

time.sleep(10)

print('代碼運行完成: %s' % sql_name)

# 多線程運行sql代碼

if __name__ == '__main__':

t1 = threading.Thread(target=read_run_write1, args=(sql1,)) # 調用函數,并傳遞參數sql1,注意當只有一個參數時,參數后面需要有逗號

t2 = threading.Thread(target=read_run_write2, args=(sql2,))

t3 = threading.Thread(target=read_run_write3, args=(sql3,))

t1.start() # 開始運行

t2.start()

t3.start()

t1.join() # 加入線程,若無join()則運行完一個主線程后則會自動跳出,運行下面的代碼,而不會等待其他線程運行完成

t2.join()

t3.join()

# 寫入數據

print('正在寫入數據')

app = xw.App(visible=False,add_book=False) # visible=False后臺打開Excel程序

wb = app.books.open(sqlpath+name+'.xlsx') # 打開給定只保留標題和公式的空模版

wb.sheets['單日'].range('A4').options(expand='table').value=result1[:].values # result[:].values寫法可以去掉索引和標題,將result1寫入到表格'單日',從A4單元格開始

wb.sheets['滾動一周'].range('A4').options(expand='table').value=result2[:].values

wb.sheets['月累計'].range('A4').options(expand='table').value=result3[:].values

filename = sqlpath+name+date+'.xlsx' # 命名新生成的excel

wb.save(filename) # 另存為新Excel,不改變模版

wb.close() # 關閉工作簿

print(filename+'已自動生成')

time_end=time.time()

print("程序運行時間:%.2f s" % (time_end-time_start))

logging.info("程序運行時間:%.2f s" % (time_end-time_start)) # 記錄程序運行時間到運行日志log.txt中

python自動化中的一些難點

多線程無法同時對excel進行寫入操作,如果直接在函數中運行完成后直接寫入,并利用多線程運行,會報錯com模塊沖突

為了解決函數不能直接生成結果變量的問題, 應先定義空DataFrame,并在函數中global聲明為調用全局變量才能達到運行完函數生成變量的效果(可能還有其他更好方法)

3ee58fd565d48edb2d6fab7d71e455c7.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/534627.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534627.shtml
英文地址,請注明出處:http://en.pswp.cn/news/534627.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql 配置郵件_SQL 郵件配置篇

exec sp_configure show advanced options,1RECONFIGURE WITHOVERRIDEgoexec sp_configure database mail xps,1RECONFIGURE WITHOVERRIDEgo--2.創建郵件帳戶信息EXECmsdb..Sysmail_add_account_spACCOUNT_NAME OCTMamiETL,--郵件帳戶名稱EMAIL_ADDRESS OCTMamiETL163.com,--發…

python 抽獎 配音樂_抖音上超好聽的神曲音樂,Python教你一次性下載

不知道什么時候開始,中國出現了南抖音、北快手的互文格局(東市買駿馬,西市買鞍韉…)。剛才提到了,之前比較喜歡刷抖音,對于我這種佛系程序猿,看網上這些整容妹子基本一個樣。喜歡抖音主要是兩個初衷,學做菜…

mysql批量寫入100萬數據_Mysql數據庫實踐操作之————批量插入數據(100萬級別的數據)-阿里云開發者社區...

第一種方法:使用insert into 插入從Redis每次獲取100條數據,根據條件去插入到Mysql數據庫中:條件:如果當前隊列中的值大于1000條,則會自動的條用該方法,該方法每次獲取從隊列的頭部每次獲取100掉數據插入到…

mysql多客戶端數據不同步_一種多終端設備上的數據同步方法

一種多終端設備上的數據同步方法【技術領域】[0001] 屬于移動通信技術領域,特別是涉及基于離網環境下多種移動終端設備之間的數 據同步的方法。 技術背景[0002] 90年代未,數據同步始于有線連接,如MAC機作為數據中心,與終端設備(iP…

oem監控mysql_OEM12c 安裝配置MySQL Plug-in用來監控MySQL

Plug-in--注冊信息[roottest agent]# /oem/emcli setup -urlhttps://omsdb.localdomain:7301/em -usernamesysmanOracle Enterprise Manager 12c 3.Copyright (c) 1996, 2013 Oracle Corporation and/or its affiliates. All rights reserved.The configuration directory &quo…

怎么利用迭代器寫入mysql_range()是什么?為什么不生產迭代器?

本篇文章給大家帶來的內容是關于range()是什么?為什么不生產迭代器?有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。迭代器是 23 種設計模式中最常用的一種(之一),在 Python 中隨處可見它的身影&#x…

java 流式_Java開發筆記(七十二)Java8新增的流式處理

通過前面幾篇文章的學習,大家應能掌握幾種容器類型的常見用法,對于簡單的增刪改和遍歷操作,各容器實例都提供了相應的處理方法,對于實際開發中頻繁使用的清單List,還能利用Arrays工具的asList方法給清單對象做初始化賦…

java保留二位小數_java使double保留兩位小數的多方法 java保留兩位小數

復制代碼代碼如下:mport java.text.DecimalFormat;DecimalFormat df new DecimalFormat("######0.00");double d1 3.23456double d2 0.0;double d3 2.0;df.format(d1);df.format(d2);df.format(d3);3個結果分別為:復制代碼代碼如下:3.230.002.00java保留兩位…

linux java jar打包_【Java】Java程序打包成jar包在Linux上運行

當需要把在Windows上開發的Java程序用在Linux上運行時,就需要吧該Java程序打包成jar包上傳到Linux上去運行。1.Java程序用MyEclipse打包成可運行的jar包(1)在MyEclipse中選中需要打包的項目,點擊右鍵,選擇:Export... 如下圖所示&a…

java匿名對象 回收_Java 匿名對象

我們知道一般實例化一個對象的格式,如下:Car car new Car();其中,變量名 car 就是 new Car() 這個對象的名字。car 是引用類型的變量,它的值存放的是對象的引用(或地址),通過 car 這個變量我們就可以間接使用對象。那…

java int 正則表達式_java正則表達式

Java正則表達式正則表達式定義了字符串的模式。正則表達式可以用來搜索、編輯或處理文本。正則表達式并不僅限于某一種語言,但是在每種語言中有細微的差別。Java正則表達式和Perl的是最為相似的。java.util.regex包主要包括以下三個類:Pattern類&#xf…

mysql.h 動態編譯命令_Linux環境編譯動態庫和靜態庫總結

對Linux環境動態庫和靜態庫的一些基礎知識做一些總結,首先總結靜態庫的編譯步驟。1 先基于.cpp或者.c文件生成對應的.o文件2將幾個.o文件 使用ar -cr命令 生成libname.a文件libname.a 為靜態庫, name 為靜態庫的名字,可以根據模塊功能命名。舉…

netbeans java中文_Ubuntu?下jdk安裝中文字體?java?解決netbeans?方塊字?中文亂碼

安裝環境Ubuntu 11.04、javajdk1.6.0_27首先找到你需要的字體,比如我就是從windows系統里拷出來的,C:\WINDOWS\Fonts這里有很多字體,我只拷貝了simsun.ttc(中文 宋體,從xp系統拷貝的,win7 下沒有這個文件)安裝java后&a…

python 教學_「Python基礎」一次就裝好Python手把手裝到好

一、前言:安裝Python有兩個主要的方法,視情況而定我兩個都會用:(1)安裝 AnacondaAnaconda像一個懶人包,安裝它等于把Python安裝好連同把Python大部分的套件也下載好了,不只如此連通較常用的Python IDE一同幫你裝到好。…

java求二維數組每行的最大值_用JAVA輸入一個二維數組a[3][4]的元素值,求輸出其元素最大值...

展開全部這個簡單啊,把所有元素遍歷一邊62616964757a686964616fe58685e5aeb931333335343963代碼:import java.util.Scanner;public class Help2 {public static void main(String[] args) {Scanner inputnew Scanner(System.in);System.out.print("…

java redis 面試題_Java開發人員怎么面試 常見Redis面試題有哪些

Java開發人員怎么面試?常見Redis面試題有哪些?Redis是目前各大企業都在使用的人們技術,也是企業選拔人才時考核的一個難題。有很多同學只是簡單了解Redis的應用,但對于為什么要用Redis以及企業面試中有關Redis的問題卻答不上來。接…

java方法重載實事例_零基礎java入門教程函數重載function實例化格式案例

java函數的重載,說白了就是函數塊函數名一樣,但函數類型和參數類型和參數列表個數不同重載之和參數列表有關系,與返回值無關java函數重載函數重載鋪墊如下圖函數重載鋪墊上圖功能顯示,功能一致所以功能一致所以用的功能函數名一致…

java 類 屬性數量_跟我學java編程—Java類的屬性與成員變量

在定義類時,經常需要抽象出它的屬性,并定義在類的主體中。下面就來介紹與屬性相關的內容。常量屬性在類中定義的屬性有常量屬性和成員屬性之分。常量屬性用final關鍵字修飾,常量只能賦值一次,在程序中不能修改它的值。一般來說&am…

java獲取界面輸入數字_通過JAVA設計 GUI 界面的計算器程序,用戶可以通過鼠標依次輸入參加計算的數值,進行加、減、乘、...

通過JAVA設計 GUI 界面的計算器程序,用戶可以通過鼠標依次輸入參加計算的數值,進行加、減、乘、2016-08-22 0 0 0 4.0分其他1積分下載如何獲取積分?通過JAVA設計 GUI 界面的計算器程序,用戶可以通過鼠標依次輸入參加計算的數值&am…

java自定義錯誤碼類_如何編寫和應用Java的自定義異常類

11.7.1編寫自定義異常類的模式編寫自定義異常類實際上是繼承一個API標準異常類,用新定義的異常處理信息覆蓋原有信息的過程。常用的編寫自定義異常類的模式如下:public class CustomException extends Exception {//或者繼承任何標準異常類public Custom…