[PYTHON] Ich möchte die Version einer DB-Tabellendefinition in einer Legacy-Umgebung verwalten, z. B. "Ich füge ein DB-Schema hinzu, das ich nicht verstehe, ohne es zu wissen ...".

Was ich machen wollte

(Ich denke, dass es derzeit nur wenige neue Dienste gibt) Ich denke, es wäre praktisch, wenn der Dienst so ist, dass jeder Entwickler die Definition nur ändert, weil sich der Master der Tabellendefinition in der Datenbank befindet (es ist für andere Entwickler schwierig zu erkennen).

Code exportieren

Dies soll nur zum ersten Mal ausgeführt werden Nachfolgende Änderungen der Tabellendefinition erfolgen in Form einer Änderung der Ausgabedatei.

"""export_database_schema.py
Wird verwendet, um die Anweisung CREATE TABLE aus der Datenbank zu exportieren
    optional arguments:
        -h, --help            show this help message and exit
        --Benutzer USER Datenbank Benutzername
        --Passwort PASSWORD Datenbank Passwort
        --Host HOST-Datenbank Hostname
        --Port PORT-Datenbank Portnummer
        --Zeichensatz CHARSET Datenbankzeichencode
        --target TARGET [TARGET ...]
Zu exportierende DB-Liste(Raum getrennt)
"""

import os
import sys
import shutil
import pymysql
import argparse

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

#Argumenteinstellung
parser = argparse.ArgumentParser()
parser.add_argument("--user", help="Datenbank-Benutzername", default="root")
parser.add_argument("--password", help="Datenbankkennwort", default="password")
parser.add_argument("--host", help="Name des Datenbankhosts", default="127.0.0.1")
parser.add_argument("--port", help="Datenbankportnummer", default=3306)
parser.add_argument("--charset", help="Datenbankzeichencode", default="utf8mb4")
parser.add_argument("--target", help="Zu exportierende DB-Liste(Raum getrennt)",
                    default=["users", "shops"],
                    nargs="+")
args = parser.parse_args()

print("Connection: mysql://%s:%s@%s:%s?charset=%s" % (
    args.user,
    args.password,
    args.host,
    args.port,
    args.charset))
con = pymysql.connect(
    user=args.user,
    password=args.password,
    host=args.host,
    port=args.port,
    charset=args.charset)

with con.cursor() as cursor:
    sql = "SHOW DATABASES"
    cursor.execute(sql)
    databases = cursor.fetchall()
    #Die Exportverarbeitung wird nur ausgeführt, wenn die angegebene Datenbank vorhanden ist.
    for d in databases:
        if d[0] not in args.target:
            continue
        #Erstellen Sie ein Verzeichnis für jede Datenbank(Einmal löschen, falls vorhanden)
        currentDirName = "%s/%s" % (ROOT_DIR, d[0])
        if os.path.isdir(currentDirName):
            shutil.rmtree(currentDirName)
        os.mkdir(currentDirName)
        dirname = "%s/schemas" % (currentDirName)
        os.mkdir(dirname)

        print("Export database: ", d[0])
        sql = "USE %s" % d[0]
        cursor.execute(sql)
        sql = "SHOW TABLES"
        cursor.execute(sql)
        tables = cursor.fetchall()
        for t in tables:
            print("\tExporting ", t[0])
            sql = "SHOW CREATE TABLE %s" % t
            cursor.execute(sql)
            schema = cursor.fetchone()
            filename = "%s/%s.sql" % (dirname, t[0])
            with open(filename, mode="w") as f:
                f.write(schema[1] + ";\n\n")

con.close()

Beispiel: "Python Export_Database_schema.py - Zielbenutzer-Shops" Die CREATE-Anweisungsdatei wird durch Ausführen mit der folgenden Verzeichnisstruktur eingerichtet.

├── users
│   └── schemas #Speichert die CREATE-Anweisung für Tabellen in der Benutzer-DB
└── shops
    └── schemas #Speichert die CREATE-Anweisung für Tabellen in der Shops-Datenbank

Code importieren

#!/bin/bash

usage() {
  cat << EOS
Usage: $0 [option]
	-t ZIEL-Zieltabellendefinitionsverzeichnis
	-d Name der DATABASE-Zieldatenbank importieren
	-H Hostname der HOST-Datenbank
	-u Benutzername der USER-Datenbank
	-p Kennwort der PASSWORD-Datenbank
	-P Portnummer der PORT-Datenbank
	-y Lassen Sie die Eingabeaufforderung zur Bestätigung der Ausführung aus
EOS
  exit 1
}

TARGET=""
DATABASE_NAME=""
HOST="127.0.0.1"
USER="root"
PASSWORD=""
PORT="3306"
AUTO_YES=false


while getopts d:t:H:u:p:P:yh OPT
do
  case $OPT in
    d) DATABASE_NAME=$OPTARG ;;
    t) TARGET=$OPTARG ;;
    H) HOST=$OPTARG ;;
    u) USER=$OPTARG ;;
    p) PASSWORD=$OPTARG ;;
    P) PORT=$OPTARG ;;
    y) AUTO_YES=true ;;
    h) usage ;;
  esac
done

ROOT_PATH=$(dirname "$(cd "$(dirname "${BASH_SOURCE:-$0}")" && pwd)")

if [ "${DATABASE_NAME}" == "" ]; then
  echo "Bitte geben Sie die zu importierende Datenbank an."
  echo "  ./$0 -d DATABASE_NAME"
  exit 1
fi

if [ ! -d $ROOT_PATH/$TARGET/schemas ]; then
  echo "Das angegebene Tabellendefinitionsverzeichnis existiert nicht"
  echo "${ROOT_PATH}Überprüfen Sie, ob das Verzeichnis unter existiert"
  echo "  ./$0 -t TARGET"
  exit 1
fi

echo "Parameter-------------------------"
echo "TARGET:		$TARGET"
echo "DATABASE_NAME:	$DATABASE_NAME"
echo "HOST:		$HOST"
echo "USER:		$USER"
echo "PASSWORD:		$PASSWORD"
echo "PORT:		$PORT"
echo "------------------------------------"

#Bestätigung
if ! "${AUTO_YES}"; then
  read -p "\"$DATABASE_NAME\"Kann ich die Datenbank initialisieren?(y/N)" yn
  case "$yn" in
    [yY]*) ;;
    *) exit 1;;
  esac
fi

echo "Datenbankinitialisierung läuft..."
CMD="mysql -h$HOST"
if [ "$USER" != "" ]; then
  CMD="$CMD -u$USER"
fi
if [ "$PASSWORD" != "" ]; then
  CMD="$CMD -p$PASSWORD"
fi
if [ "$PORT" != "" ]; then
  CMD="$CMD -P$PORT"
fi

echo 'SET FOREIGN_KEY_CHECKS = 0;' > "${ROOT_PATH}/tmp.sql"
cat $ROOT_PATH/$TARGET/schemas/*.sql >> "${ROOT_PATH}/tmp.sql"

`$CMD -e "set FOREIGN_KEY_CHECKS=0; DROP DATABASE IF EXISTS $DATABASE_NAME;"`
`$CMD -e "CREATE DATABASE $DATABASE_NAME;"`
`$CMD -t $DATABASE_NAME < "${ROOT_PATH}/tmp.sql"`

rm "${ROOT_PATH}/tmp.sql"
echo "Erledigt"

#Wenn Sie die Anfangsdaten zum Testen bereitstellen möchten, platzieren Sie die Datei im folgenden Format und importieren Sie sie zusammen
# echo "Anfangsdaten erstellen..."
# `$CMD -t $DATABASE_NAME < "${ROOT_PATH}/${TARGET}/testdata/dump.sql"`
# echo "Erledigt"

exit 0

Import ist Als Beispiel "./scripts/import_database_schema.sh -t Benutzer -d Benutzer -y" Ich werde es in Form von tun.

Im tatsächlichen Betrieb werden die Testdaten wie unten gezeigt eingerichtet, und die Testdaten werden zum Zeitpunkt des Imports ebenfalls importiert, und der Test wird mit Github-Aktionen ausgeführt.

├── users
│   ├── testdata #Speichert Testdaten der Benutzer-DB
│   └── schemas  #Speichert die CREATE-Anweisung für Tabellen in der Benutzer-DB
└── shops
    ├── testdata #Speichert Testdaten der Shop-DB
    └── schemas  #Speichert die CREATE-Anweisung für Tabellen in der Shops-Datenbank

Recommended Posts

Ich möchte die Version einer DB-Tabellendefinition in einer Legacy-Umgebung verwalten, z. B. "Ich füge ein DB-Schema hinzu, das ich nicht verstehe, ohne es zu wissen ...".
Ich möchte eine in Python in PDF konvertierte Tabelle wieder in CSV konvertieren
Ich möchte eine Python-Umgebung erstellen
Ich möchte eine schöne Python-Entwicklungsumgebung für meinen neuen Mac erstellen
Ich möchte eine Prioritätswarteschlange erstellen, die mit Python (2.7) aktualisiert werden kann.
Ich möchte einen Lebenszyklus in der Aufgabendefinition von ECS festlegen
Python-Programm ist langsam! Ich möchte beschleunigen! In einem solchen Fall ...