PythonとTkinterを使って大量のカラム名を管理

プログラミング

データベースやCSVファイルを扱う際、大量のカラム名を管理するのは非常に手間がかかります。カラム数が多いと、どのカラムがどのデータを指しているのか分からなくなりがちです。この記事では、PythonとTkinterを使って、カラム名を効率的に管理・検索できるツールを作ってみたので紹介します。

1. 基本のサンプルコード

まずは、カラム名を検索できる基本的なツールを作成してみましょう。以下のコードでは、カラム名、GUI表示名、CSV名を表示し、それぞれを検索できる機能を備えたTkinterアプリケーションを作成します。

コード例:カラム名検索ツール

import tkinter as tk
from tkinter import ttk

class ColumnSearcherApp(tk.Tk):
    def __init__(self, columns):
        super().__init__()

        self.title("カラム名検索ツール")
        self.geometry("600x400")

        self.columns = columns

        # 検索フレーム
        self.search_frame = tk.Frame(self)
        self.search_frame.pack(pady=10)

        # 検索ラベルとエントリ
        tk.Label(self.search_frame, text="カラム名:").grid(row=0, column=0, padx=5)
        self.search_var = tk.StringVar()
        self.search_var.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry = tk.Entry(self.search_frame, textvariable=self.search_var)
        self.search_entry.grid(row=0, column=1, padx=5)

        tk.Label(self.search_frame, text="項目名:").grid(row=1, column=0, padx=5)
        self.search_var_gui = tk.StringVar()
        self.search_var_gui.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_gui = tk.Entry(self.search_frame, textvariable=self.search_var_gui)
        self.search_entry_gui.grid(row=1, column=1, padx=5)

        tk.Label(self.search_frame, text="CSV名:").grid(row=2, column=0, padx=5)
        self.search_var_csv = tk.StringVar()
        self.search_var_csv.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_csv = tk.Entry(self.search_frame, textvariable=self.search_var_csv)
        self.search_entry_csv.grid(row=2, column=1, padx=5)

        # 一覧表示用ツリービュー
        self.tree = ttk.Treeview(self, columns=("column_name", "gui_name", "csv_name"), show='headings')
        self.tree.heading("column_name", text="カラム名")
        self.tree.heading("gui_name", text="項目名")
        self.tree.heading("csv_name", text="CSV名")
        self.tree.pack(fill=tk.BOTH, expand=True)

        self.populate_tree()

    def populate_tree(self):
        for col in self.columns:
            self.tree.insert("", tk.END, values=(col["column_name"], col["gui_name"], col["csv_name"]))

    def search_columns(self):
        query_col = self.search_var.get().lower()
        query_gui = self.search_var_gui.get().lower()
        query_csv = self.search_var_csv.get().lower()

        # 一覧をクリア
        for i in self.tree.get_children():
            self.tree.delete(i)

        # フィルタされた結果を表示
        for col in self.columns:
            if query_col in col["column_name"].lower() and query_gui in col["gui_name"].lower() and query_csv in col["csv_name"].lower():
                self.tree.insert("", tk.END, values=(col["column_name"], col["gui_name"], col["csv_name"]))


if __name__ == "__main__":
    # サンプルデータの作成
    columns = [
        {"column_name": "user_id", "gui_name": "ユーザーID", "csv_name": "user_id"},
        {"column_name": "order_date", "gui_name": "注文日", "csv_name": "order_date"},
        {"column_name": "total_price", "gui_name": "合計金額", "csv_name": "total_price"},
        # 他のカラムをここに追加
    ]
    
    app = ColumnSearcherApp(columns)
    app.mainloop()

解説

このコードでは、サンプルデータを使ってカラム名、GUI表示名、CSVでの項目名を一覧表示し、ユーザーが各項目で検索できるツールを提供します。これにより、基本的なカラム管理ツールが動作することが確認できます。

2. では実際に使うとしたら…

このサンプルコードを試した後、実際に使う場合には、以下のようにExcelやSQLite3データベースを利用してカラム情報を管理し、ツールで使用することができます。

Excelで管理するなら

Excelファイルにカラム情報を保存し、Pandasを使って読み込む方法です。この方法を使うと、Excelファイルの内容を変更するだけで、ツールの表示内容も簡単に更新できます。

Excelファイルの準備

まず、カラム情報を管理するためのExcelファイルを作成します。以下のリンクから、サンプルのExcelファイルをダウンロードできます。

Excelファイルからデータを読み込んでツールを起動

次に、Excelファイルからデータを読み込んで表示するためのコードを以下に示します。

import pandas as pd
import tkinter as tk
from tkinter import ttk

class ColumnSearcherApp(tk.Tk):
    def __init__(self, columns):
        super().__init__()

        self.title("カラム名検索ツール")
        self.geometry("600x400")

        self.columns = columns

        # 検索フレーム
        self.search_frame = tk.Frame(self)
        self.search_frame.pack(pady=10)

        # 検索ラベルとエントリ
        tk.Label(self.search_frame, text="カラム名:").grid(row=0, column=0, padx=5)
        self.search_var = tk.StringVar()
        self.search_var.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry = tk.Entry(self.search_frame, textvariable=self.search_var)
        self.search_entry.grid(row=0, column=1, padx=5)

        tk.Label(self.search_frame, text="項目名:").grid(row=1, column=0, padx=5)
        self.search_var_gui = tk.StringVar()
        self.search_var_gui.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_gui = tk.Entry(self.search_frame, textvariable=self.search_var_gui)
        self.search_entry_gui.grid(row=1, column=1, padx=5)

        tk.Label(self.search_frame, text="CSV名:").grid(row=2, column=0, padx=5)
        self.search_var_csv = tk.StringVar()
        self.search_var_csv.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_csv = tk.Entry(self.search_frame, textvariable=self.search_var_csv)
        self.search_entry_csv.grid(row=2, column=1, padx=5)

        # 一覧表示用ツリービュー
        self.tree = ttk.Treeview(self, columns=("column_name", "gui_name", "csv_name"), show='headings')
        self.tree.heading("column_name", text="カラム名")
        self.tree.heading("gui_name", text="項目名")
        self.tree.heading("csv_name", text="CSV名")
        self.tree.pack(fill=tk.BOTH, expand=True)

        self.populate_tree()

    def populate_tree(self):
        for col in self.columns:
            self.tree.insert("", tk.END, values=(col["column_name"], col["gui_name"], col["csv_name"]))

    def search_columns(self):
        query_col = self.search_var.get().lower()
        query_gui = self.search_var_gui.get().lower()
        query_csv = self.search_var_csv.get().lower()

        # 一覧をクリア
        for i in self.tree.get_children():
            self.tree.delete(i)

        # フィルタされた結果を表示
        for col in self.columns:
            if query_col in col["column_name"].lower() and query_gui in col["gui_name"].lower() and query_csv in col["csv_name"].lower():
                self.tree.insert("", tk.END, values=(col["column_name"], col["gui_name"], col["csv_name"]))


if __name__ == "__main__":
    # Excelファイルからデータを読み込む
    df = pd.read_excel('columns.xlsx')
    columns = df.to_dict(orient='records')

    app = ColumnSearcherApp(columns)
    app.mainloop()

データベースで管理するなら

次に、SQLite3データベースにカラム情報を保存し、それを読み込んで表示する方法です。この方法では、データベースを使用することで、より多くのデータを扱うことができます。

Excelファイルからデータベースに保存

まず、Excelファイルからカラム情報を読み込み、それをSQLite3データベースに保存するコードを示します。

import pandas as pd
import sqlite3

# Excelファイルからデータを読み込む
df = pd.read_excel('columns.xlsx')

# SQLite3データベースに接続
conn = sqlite3.connect('columns.db')
cursor = conn.cursor()

# テーブルを作成
cursor.execute('''
CREATE TABLE IF NOT EXISTS column_table (
    id INTEGER PRIMARY KEY,
    column_name TEXT,
    gui_name TEXT,
    csv_name TEXT
)
''')

# データを挿入
for _, row in df.iterrows():
    cursor.execute('''
    INSERT INTO column_table (column_name, gui_name, csv_name)
    VALUES (?, ?, ?)
    ''', (row['column_name'], row['gui_name'], row['csv_name']))

# コミットしてデータベースを閉じる
conn.commit()
conn.close()

データベースから読み込んで表示

次に、データベースに保存されたカラム情報を読み込み、表示するためのコードです。

import sqlite3
import tkinter as tk
from tkinter import ttk, messagebox

class ColumnSearcherApp(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title("カラム名管理ツール")
        self.geometry("700x500")

        # データベースに接続
        self.conn = sqlite3.connect('columns.db')
        self.cursor = self.conn.cursor()

        # UIセットアップ
        self.create_widgets()
        self.populate_tree()

    def create_widgets(self):
        # 検索フレーム
        self.search_frame = tk.Frame(self)
        self.search_frame.pack(pady=10)

        tk.Label(self.search_frame, text="カラム名:").grid(row=0, column=0, padx=5)
        self.search_var = tk.StringVar()
        self.search_var.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry = tk.Entry(self.search_frame, textvariable=self.search_var)
        self.search_entry.grid(row=0, column=1, padx=5)

        tk.Label(self.search_frame, text="項目名:").grid(row=1, column=0, padx=5)
        self.search_var_gui = tk.StringVar()
        self.search_var_gui.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_gui = tk.Entry(self.search_frame, textvariable=self.search_var_gui)
        self.search_entry_gui.grid(row=1, column=1, padx=5)

        tk.Label(self.search_frame, text="CSV名:").grid(row=2, column=0, padx=5)
        self.search_var_csv = tk.StringVar()
        self.search_var_csv.trace("w", lambda name, index, mode: self.search_columns())
        self.search_entry_csv = tk.Entry(self.search_frame, textvariable=self.search_var_csv)
        self.search_entry_csv.grid(row=2, column=1, padx=5)

        # 一覧表示用ツリービュー
        self.tree = ttk.Treeview(self, columns=("column_name", "gui_name", "csv_name"), show='headings')
        self.tree.heading("column_name", text="カラム名")
        self.tree.heading("gui_name", text="項目名")
        self.tree.heading("csv_name", text="CSV名")
        self.tree.pack(fill=tk.BOTH, expand=True)

        self.populate_tree()

        # 手動入力フレーム
        self.entry_frame = tk.Frame(self)
        self.entry_frame.pack(pady=10)

        tk.Label(self.entry_frame, text="カラム名:").grid(row=0, column=0, padx=5)
        self.entry_col = tk.Entry(self.entry_frame)
        self.entry_col.grid(row=0, column=1, padx=5)

        tk.Label(self.entry_frame, text="項目名:").grid(row=1, column=0, padx=5)
        self.entry_gui = tk.Entry(self.entry_frame)
        self.entry_gui.grid(row=1, column=1, padx=5)

        tk.Label(self.entry_frame, text="CSV名:").grid(row=2, column=0, padx=5)
        self.entry_csv = tk.Entry(self.entry_frame)
        self.entry_csv.grid(row=2, column=1, padx=5)

        self.add_button = tk.Button(self.entry_frame, text="追加", command=self.add_column)
        self.add_button.grid(row=3, columnspan=2, pady=10)

    def populate_tree(self):
        # 現在のツリービューをクリア
        for i in self.tree.get_children():
            self.tree.delete(i)

        # データベースからデータを取得して表示
        self.cursor.execute("SELECT column_name, gui_name, csv_name FROM column_table")
        for row in self.cursor.fetchall():
            self.tree.insert("", tk.END, values=row)

    def search_columns(self):
        query_col = self.search_var.get().lower()
        query_gui = self.search_var_gui.get().lower()
        query_csv = self.search_var_csv.get().lower()

        # 一覧をクリア
        for i in self.tree.get_children():
            self.tree.delete(i)

        # フィルタされた結果を表示
        self.cursor.execute("SELECT column_name, gui_name, csv_name FROM column_table")
        for row in self.cursor.fetchall():
            if query_col in row[0].lower() and query_gui in row[1].lower() and query_csv in row[2].lower():
                self.tree.insert("", tk.END, values=row)

    def add_column(self):
        col_name = self.entry_col.get()
        gui_name = self.entry_gui.get()
        csv_name = self.entry_csv.get()

        if col_name and gui_name and csv_name:
            self.cursor.execute('''
            INSERT INTO column_table (column_name, gui_name, csv_name)
            VALUES (?, ?, ?)
            ''', (col_name, gui_name, csv_name))
            self.conn.commit()
            messagebox.showinfo("追加完了", "カラム情報を追加しました。")
            self.populate_tree()
        else:
            messagebox.showwarning("入力エラー", "すべてのフィールドに入力してください。")

    def __del__(self):
        self.conn.close()

if __name__ == "__main__":
    app = ColumnSearcherApp()
    app.mainloop()

まとめ

これで、Excelファイルからの読み込み、データベースへの保存、手動での追加を備えた完全なツールが完成しました。このツールを使用することで、大量のカラム名を効率的に管理できるだけでなく、実際の業務に即した柔軟な対応が可能になります。

一度このツールを使ってデータ管理を効率化してみてください!



コメント

タイトルとURLをコピーしました