MySQL-Datenbankdesign: Detaillierte Erläuterung der Schema-Operationsmethode mit Python

MySQL-Datenbankdesign: Detaillierte Erläuterung der Schema-Operationsmethode mit Python

Bevor der Pfeil abgeschossen wurde, flüsterte der Bogen dem Pfeil zu: „Deine Freiheit gehört mir.“ Schema ist wie ein Pfeil und der Bogen ist wie Python. Die Wahl von Python ist die größte Freiheit von Schema. Und Freiheit sollte eine Chance sein, sich zu verbessern.

Was ist Schema?

Unabhängig davon, welche Anwendung wir erstellen, gilt bei der Verarbeitung von Benutzereingaben ein Grundsatz: Vertrauen Sie niemals den Eingabedaten des Benutzers. Das bedeutet, dass wir Benutzereingaben streng validieren müssen. Bei der Entwicklung einer Webanwendung werden Eingabedaten normalerweise in Form von JSON an die Backend-API gesendet, und die API muss die Eingabedaten validieren. Normalerweise füge ich viele Urteile und verschiedene Wenns hinzu, was den Code sehr hässlich macht. Gibt es eine elegantere Möglichkeit, Benutzerdaten zu überprüfen? Hier kommt Schema ins Spiel.

(Ⅰ)MySQLdb-Teil

Tabellenstruktur:

mysql> verwende Sakila; 
mysql> Beschreibung Schauspieler; 
+-------------+----------------------+------+-----+-------------------+-----------------------------+ 
| Feld | Typ | Null | Schlüssel | Standard | Extra | 
+-------------+----------------------+------+-----+-------------------+-----------------------------+ 
| Schauspieler-ID | smallint(5) unsigniert | NEIN | PRI | NULL | auto_increment | 
| Vorname | varchar(45) | NEIN | | NULL | | 
| Nachname | varchar(45) | NEIN | MUL | NULL | | 
| letztes_Update | Zeitstempel | NEIN | | AKTUELLER_ZEITSTEMPEL | bei Update AKTUELLER_ZEITSTEMPEL | 
+-------------+----------------------+------+-----+-------------------+-----------------------------+ 
4 Zeilen im Satz (0,00 Sek.)

Datenbankverbindungsmodul:

[root@DataHacker ~]# cat dbapi.py 
#!/usr/bin/env ipython 
#Kodierung = utf-8 
#Autor: [email protected] 
#Zeit: 29.1.2014 
 
MySQLdb als dbapi importieren 
 
BENUTZER = "root" 
PASSWD = "Oracle" 
HOST = '127.0.0.1' 
DB = 'sakila' 
 
conn = dbapi.connect(Benutzer=BENUTZER,Passwort=PASSW,Host=HOST,DB=DB)

1 Spaltenmetadaten drucken

[root@DataHacker ~]# cat QueryColumnMetaData.py 
#!/usr/bin/env ipython 
 
von dbapi import * 
 
cur = conn.cursor() 
Anweisung = """Wählen Sie * ab Schauspielerlimit 1""" 
cur.execute(Anweisung) 
 
print "Ausgabespaltenmetadaten..." 
drucken 
für Datensatz in aktueller Beschreibung: 
  Datensatz drucken 
 
aktuell.schließen() 
conn.close()

1.) Nach dem Aufruf von execute() sollte der Cursor sein Beschreibungsattribut setzen
2.) Es ist ein Tupel mit 7 Spalten: Spaltenname, Typ, Anzeigegröße, interne Größe, Genauigkeit, Bereich und ein Flag, um anzugeben, ob Nullwerte akzeptiert werden

[root@DataHacker ~]# chmod +x QueryColumnMetaData.py 
[root@DataHacker ~]# ./QueryColumnMetaData.py 
Metadaten der Ausgabespalte... 
 
('Schauspieler-ID', 2, 1, 5, 5, 0, 0) 
('Vorname', 253, 8, 45, 45, 0, 0) 
('Nachname', 253, 7, 45, 45, 0, 0) 
('letztes_Update', 7, 19, 19, 19, 0, 0)

2 Zugriff auf Spaltenwerte über den Spaltennamen

Standardmäßig ist der von der get-Methode als „Zeile“ aus der Datenbank zurückgegebene Wert ein Tupel

In [1]: von dbapi import * 
In [2]: cur = conn.cursor() 
In [3]: v_sql = "select actor_id,last_name aus dem Schauspielerlimit 2" 
In [4]: ​​​​cur.execute(v_sql) 
Aus[4]: 2L 
In [5]: Ergebnisse = cur.fetchone() 
In [6]: Ergebnisse drucken[0] 
58 
In [7]: Ergebnisse drucken[1] 
AKROYD

Wir können das Cursorclass-Attribut verwenden, um es als Wörterbuch zurückzugeben

In [2]: importiere MySQLdb.cursors 
In [3]: importiere MySQLdb 
In [4]: ​​​​conn = MySQLdb.connect(user='root',passwd='oracle',host='127.0.0.1',db='sakila',cursorclass=MySQLdb.cursors.DictCursor) 
In [5]: cur = conn.cursor() 
In [6]: v_sql = "select actor_id,last_name from actor limit 2" 
In [7]: cur.execute(v_sql) 
Aus[7]: 2L 
In [8]: Ergebnisse = cur.fetchone() 
In [9]: drucke Ergebnisse['actor_id'] 
58 
In [10]: drucke Ergebnisse['Nachname'] 
AKROYD

2. SQLAlchemy – SQL Alchemist

Obwohl es für SQL internationale Standards gibt, interpretiert leider jeder Datenbankanbieter diese Standards anders und implementiert auf Grundlage der Standards seine eigene private Syntax. Um die Unterschiede zwischen verschiedenen SQL-Dialekten zu verbergen, wurden Tools wie SQLAlchemy entwickelt.

SQLAlchemy-Verbindungsmodul:

[root@DataHacker Desktop]# cat sa.py 
importiere sqlalchemy als sa 
Engine = sa.create_engine('mysql://root:[email protected]/testdb',pool_recycle=3600) 
Metadaten = sa.MetaData()

Beispiel 1: Tabellendefinition

In [3]: t = Tabelle('t',Metadaten, 
   ...: Spalte('id',Integer), 
   ...: Spalte('Name',VARCHAR(20)), 
   ...: mysql_engine='InnoDB', 
   ...: mysql_charset='utf8' 
   ... : ) 
 
In [4]: ​​t.create(bind=engine)

Beispiel 2: Tabellenlöschung

Es gibt zwei Möglichkeiten, eine davon ist: 
In [5]: t.drop(bind=engine,checkfirst=True)  
Ein anderes ist: 
In [5]: metadata.drop_all(bind=engine,checkfirst=True), wobei Sie das Attribut tables verwenden können, um die zu löschenden Objekte anzugeben.

Beispiel 3: 5 Einschränkungen

3.1 Primärschlüssel 
Die folgenden zwei Methoden sind beide akzeptabel, eine auf Spaltenebene und die andere auf Tabellenebene. In [7]: t_pk_col = Table('t_pk_col',metadata,Column('id',Integer,primary_key=True),Column('name',VARCHAR(20))) 
In [8]: t_pk_col.create(bind=engine) 
In [9]: t_pk_tb = Tabelle('t_pk_01',Metadaten,Spalte('id',Integer),Spalte('name',VARCHAR(20)),PrimaryKeyConstraint('id','name',name='prikey')) 
In [10]: t_pk_tb.create(bind=engine) 
3.2 Fremdschlüssel 
In [13]: t_fk = Table('t_fk',metadata,Column('id',Integer,ForeignKey('t_pk.id'))) 
In [14]: t_fk.create(bind=engine) 
In [15]: t_fk_tb = Tabelle('t_fk_tb',Metadaten,Spalte('col1',Integer),Spalte('col2',VARCHAR(10)),ForeignKeyConstraint(['col1','col2'],['t_pk.id','t_pk.name'])) 
In [16]: t_fk_tb.create(bind=engine) 
3.3 einzigartig 
In [17]: t_uni = Tabelle('t_uni',Metadaten,Spalte('id',Integer,unique=True)) 
In [18]: t_uni.create(bind=engine) 
In [19]: t_uni_tb = Tabelle('t_uni_tb',Metadaten,Spalte('col1',Integer),Spalte('col2',VARCHAR(10)),UniqueConstraint('col1','col2')) 
In [20]: t_uni_tb.create(bind=engine) 
3.4 Prüfung 
   Obwohl es funktionieren würde, unterstützt MySQL derzeit keine Prüfeinschränkungen. Ich werde hier keine Beispiele geben. 
3.5 nicht null 
In [21]: t_null = Tabelle('t_null',Metadaten,Spalte('id',Integer,nullable=Falsch)) 
In [22]: t_null.create(bind=engine)

4 Standardwerte

Es gibt zwei Kategorien: pessimistisch (Werte werden vom DB-Server bereitgestellt) und optimistisch (Werte werden von SQLAlshemy bereitgestellt), wobei optimistisch in folgende Kategorien unterteilt werden kann: Einfügen und Aktualisieren

4.1 Beispiel: insert 
In [23]: t_def_inser = Tabelle('t_def_inser',metadata,Spalte('id',Integer),Spalte('name',VARCHAR(10),server_default='cc')) 
In [24]: t_def_inser.create(bind=engine) 
3.2 Beispiel: update 
In [25]: t_def_upda = Tabelle('t_def_upda',metadata,Spalte('id',Integer),Spalte('name',VARCHAR(10),server_onupdate='DataHacker')) 
In [26]: t_def_upda.create(bind=engine) 
3.3 Beispiel: Passiv  
In [27]: t_def_pass = Tabelle('t_def_pass',metadata,Spalte('id',Integer),Spalte('name',VARCHAR(10),DefaultClause('cc'))) 
In [28]: t_def_pass.create(bind=engine)

3. Schema ausblenden

Die Frage, ob die Sicherheit von Daten einem absolut vertrauenswürdigen Objekt ausgesetzt ist, ist ein Risiko, das kein sicherheitsbewusster DBA eingehen würde. Ein besserer Ansatz besteht darin, die Schemastruktur so weit wie möglich zu verbergen und die Integrität der vom Benutzer eingegebenen Daten zu überprüfen. Obwohl dies die Betriebs- und Wartungskosten in gewissem Maße erhöht, ist die Sicherheit von größter Bedeutung.

Hier verwenden wir die Entwicklung eines Kommandozeilentools, um dieses Problem zu veranschaulichen

Anforderungen: Tabellenstruktur ausblenden, dynamische Abfrage implementieren und MySQL \G-Ausgabe der Ergebnisse simulieren

Version: 
[root@DataHacker ~]# ./sesc.py --version 
1.0 
Hilfe anzeigen: 
[root@DataHacker ~]# ./sesc.py -h 
Verwendung: sesc.py [Optionen] <arg1> <arg2> [<arg3>...] 
Optionen: 
 --version zeigt die Versionsnummer des Programms an und beendet das Programm 
 -h, --help zeigt diese Hilfemeldung an und beendet das Programm 
 -q TERM weist Where-Prädikat zu 
 -c COL, --column=COL Abfragespalte zuweisen 
 -t TABLE Abfragetabelle zuweisen 
 -f, --format -f muss mit -o übereinstimmen 
 -o OUTFILE Ausgabedatei zuweisen 
Der gewünschte Effekt: 
[root@DataHacker ~]# ./sesc.py -t Schauspieler -c Nachname -qs% -f -o Ausgabe.txt 
[root@DataHacker ~]# cat Ausgabe.txt 
************ 1 Reihe ******************* 
Schauspieler-ID: 180 
Vorname: JEFF 
Nachname: SILVERSTONE 
letzte Aktualisierung: 15.02.2006 04:34:33 
************ 2 Reihe ******************* 
Schauspieler-ID: 195 
Vorname: JAYNE 
Nachname: SILVERSTONE 
letzte Aktualisierung: 15.02.2006 04:34:33 
......<der Großteil der Ausgabe wurde hier ausgelassen>......

Bitte beachten Sie den Code

#!/usr/bin/env python
optparse importieren
von dbapi import *

#Erstellen Sie eine OptionParser-Instanz und konfigurieren Sie die erwarteten Optionen parser = optparse.OptionParser(usage="%prog [options] <arg1> <arg2> [<arg3>...]",version='1.0',)
#Definieren Sie Befehlszeilenoptionen und verwenden Sie add_option, um jeweils eine hinzuzufügen.parser.add_option("-q",action="store",type="string",dest="term",help="assign where predicate")
parser.add_option("-c","--column",action="store",type="string",dest="col",help="Abfragespalte zuweisen")
parser.add_option("-t",action="store",type="string",dest="table",help="Abfragetabelle zuweisen")
parser.add_option("-f","--format",action="store_true",dest="format",help="-f muss mit -o übereinstimmen")
parser.add_option("-o",action="store",type="string",dest="outfile",help="Ausgabedatei zuweisen")
#Befehlszeilenoptionen analysieren, args = parser.parse_args()
#Weisen Sie den obigen Zielwert unserer benutzerdefinierten Variablentabelle = options.table zu
Spalte = Optionen.Spalte
Begriff = Optionen.Begriff
format = Optionen.format
# Implementieren Sie eine dynamische Leseabfrageanweisung = "select * from %s where %s like '%s'"%(table,column,term)
cur = conn.cursor()
cur.execute(Anweisung)
Ergebnisse = cur.fetchall()
#Simulieren Sie das \G-Ausgabeformat, wenn das Format True ist:
 columns_query = "beschreibe %s"%(Tabelle)
 cur.execute(Spaltenabfrage)
 gehört = aktuell.fetchall()
 Spaltenliste = []
 zur Aufzeichnung in Anhörungen:
  Spaltenliste.Anhängen(Datensatz[0])
 Ausgabe = ""
 Anzahl = 1
 zur Aufzeichnung in den Ergebnissen:
  Ausgabe = Ausgabe + "************ %s Zeile ************\n\n"%(Anzahl)
  für Feldnummer in xrange(0, Länge(Spaltenliste)):
   Ausgabe = Ausgabe + Spaltenliste[Feldnr.]+ ": " + str(Datensatz[Feldnr.]) + "\n"
  Ausgabe = Ausgabe + "\n"
  Anzahl = Anzahl + 1
anders:
 Ausgabe = []
 für Datensatz in xrange(0,len(Ergebnisse)):
  Ausgabe.Anhängen(Ergebnisse[Datensatz])
 Ausgabe = ''.join(Ausgabe)
#Leiten Sie die Ausgabeergebnisse in die angegebene Datei weiter, wenn options.outfile:
 outfile = Optionen.outfile
 mit open(outfile,'w') als out:
  out.write(Ausgabe)
anders:
 Druckausgabe
#Cursor und Verbindung schließen conn.close()
aktuell.schließen()

Zusammenfassen

Dies ist der gesamte Inhalt dieses Artikels zur detaillierten Erläuterung der Schemaoperationsmethode mit Python im MySQL-Datenbankdesign. Ich hoffe, er wird für alle hilfreich sein. Gerne können Sie sich folgende Themen ansehen: Beispielcode für Python-Timer, Freigabe von Code für die digitale Bildgenerierung in Python usw. Wenn Sie Fragen haben, können Sie jederzeit eine Nachricht hinterlassen. Der Herausgeber wird Ihnen rechtzeitig antworten. Gerne können Sie zur Diskussion eine Nachricht hinterlassen.

Das könnte Sie auch interessieren:
  • Python implementiert die Datenvalidierung durch Schema
  • Python exportiert den Schemabeispielcode der Hive-Datentabelle
  • So lesen Sie Parquet-Dateien auf HDFS mit Python
  • Lösen Sie das Problem der Konvertierung von XML-Dateien in TXT-Dateien in Python (Methode xml.etree).
  • So schreiben Sie ein Wörterbuch als JSON-Datei in Python
  • So fügen Sie mithilfe der Python-Standardbibliothek „zipfile“ Ordner zu einem komprimierten Paket hinzu
  • Python-Dateiverarbeitung - Detaillierte Erklärung zum Lesen und Schreiben von Dateien
  • Verwenden Sie Python, um das Schema zu definieren und Parquet-Dateidetails zu generieren

<<:  Geben Sie einige Tipps zur Verwendung von JavaScript-Operatoren

>>:  Springboot integriert die Docker-Bereitstellung, um zwei Möglichkeiten zum Erstellen von Docker-Images zu implementieren

Artikel empfehlen

Beispiel einer DOM-Operationstabelle (DOM erstellt Tabelle)

1. Erstellen Sie eine Tabelle mit HTML-Tags: Code...

Ausführliche Erläuterung der Vue-Komponente „Multi-Select-Liste“

Eine Mehrfachauswahl ist ein Benutzeroberflächene...

Tipps zur Verwendung des Befehls „Docker Inspect“

Beschreibung und Einführung Docker Inspect ist ei...

Diskussion über die numerische Begrenzung des OL-Elements im HTML-Dokument

Im Allgemeinen ist es unwahrscheinlich, dass Sie ...

Verwenden Sie Element+vue, um Start- und Endzeitlimits zu implementieren

In diesem Artikelbeispiel wird der spezifische Co...

So unterstreichen Sie das A-Tag und ändern die Farbe vor und nach dem Klicken

Code kopieren Der Code lautet wie folgt: ein:link...

Ursachen und Lösungen für domänenübergreifende Probleme bei Ajax-Anfragen

Inhaltsverzeichnis 1. Wie entsteht Cross-Domain? ...

So vermeiden Sie die URL-Zeitzonenfalle in MySQL

Vorwort Wenn Sie MySQL 6.0.x oder höher (JAR) ver...

Analyse der MySQL-Transaktionsmerkmale und Ebenenprinzipien

1. Was ist eine Transaktion? Eine Datenbanktransa...