Oracle複数行INSERT をExcelから、Python でSQL文を作る

Oracle 複数行INSERTのSQL は、
INSERT ALL
INTOテーブル名 [ ( column, ,,,) ] VALUES ( ・・・)
INTOテーブル名 [ ( column, ,,,) ] VALUES ( ・・・)
SELECT 1 FROM DUAL
で、INTOテーブル名 各行に付けなければならない不便さから解放されるために、
Excel で格納するデータ値を書いて、PythonSQLを生成する。

Excel の書き方の規則を定めておく。
・シート名にテーブル名
・1行目はカラム名
・2行目以降が値
Excel ファイル、シートに対して ”シート名.sql” のSQLスクリプトを生成する。

Python 実行環境として、openpyxl をインストールしておく。
makeInsertSQL.py

# -*- coding: utf-8 -*-
import datetime
import openpyxl
import sys
import os
from pathlib import Path

class MakeInsertSQL(object):
    def __init__(self, file):
        self.book = openpyxl.load_workbook(file)
    def exec(self):
        for name in self.book.sheetnames:
            self.create(name)
    def create(self, sheetName):
        sqlfile = "%s/%s.sql" % (Path(__file__).parent.resolve(), sheetName)
        with open(sqlfile, 'w', encoding='utf-8') as f:
            f.write("INSERT ALL\n")
            sheet = self.book[sheetName]
            row = list(sheet.values)
            columns = ", ".join(row[0])
            for r in row[1:]:
                vary = []
                for cell in r:
                    if type(cell) is str:
                        vary.append("'%s'" % cell)
                    elif type(cell) is int:
                        vstr = "%d" % cell
                        vary.append(vstr)
                    elif type(cell) is datetime.datetime:
                        vary.append("TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS')" % cell.strftime('%Y-%m-%d %H:%M:%S'))
                    elif cell is None:
                        vary.append("NULL")
                v = ", ".join(vary)
                f.write("INTO %s (%s) VALUES(%s)\n" % (sheetName, columns, v))
            f.write("SELECT 1 FROM DUAL\n")
        print("created : %s" % sqlfile)

if __name__ == '__main__':
    args = sys.argv
    if len(args) == 2:
        if os.path.isfile(args[1]):
            maker = MakeInsertSQL(args[1])
            maker.exec()
        else:
            print("Not Found %s" % args[1])
    else:
        print("Usage: makeInsertSQL.py Excelfile")

openpyxl でシート名を指定して読込む時、
 self.book.get_sheet_by_name(sheetName) を使うと

DeprecationWarning: Call to deprecated function get_sheet_by_name (Use wb[sheetname]).
と、警告が出るので、book[ sheetName ] で読み込む。
openpyxl は、ブック .values() が返すものはジェネレータであるので、list() で各行のリストにして
処理する。
日付も、日付時刻も、openpyxl は、datetime.datetime として読み取る。
文字列は、str 数値は、int で type が返ってくるのでそれで VALUES 文を組み立てる。

(実行例)

こういうExcel を用意して実行すると
T_USER.sql は、以下のとおり作成される。

INSERT ALL
INTO T_USERS (UID, FIRST_NAME, LAST_NAME, AGE, UPDATE_TIME) VALUES(1, '太郎', '山田', 34, TO_TIMESTAMP('2023-05-01 12:23:47', 'YYYY-MM-DD HH24:MI:SS'))
INTO T_USERS (UID, FIRST_NAME, LAST_NAME, AGE, UPDATE_TIME) VALUES(2, '次郎', '山田', 32, TO_TIMESTAMP('2023-05-01 09:28:09', 'YYYY-MM-DD HH24:MI:SS'))
SELECT 1 FROM DUAL