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 [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:
|
<<: Geben Sie einige Tipps zur Verwendung von JavaScript-Operatoren
1. Erstellen Sie eine Tabelle mit HTML-Tags: Code...
Eine Mehrfachauswahl ist ein Benutzeroberflächene...
Verwenden Sie CSS3, um das Eingabefeld ähnlich de...
Beschreibung und Einführung Docker Inspect ist ei...
Im Allgemeinen ist es unwahrscheinlich, dass Sie ...
In diesem Artikelbeispiel wird der spezifische Co...
Code kopieren Der Code lautet wie folgt: ein:link...
Laden Sie die Windows-Version von Nginx von der o...
Inhaltsverzeichnis 1. Wie entsteht Cross-Domain? ...
1. Um die Abfrage zu optimieren, sollten Sie voll...
NProgress ist der Fortschrittsbalken, der oben im...
Vorwort Wenn Sie MySQL 6.0.x oder höher (JAR) ver...
(I) Methode 1: Vorab direkt im Skript-Tag definie...
1. Was ist eine Transaktion? Eine Datenbanktransa...
Dieser Artikel verwendet die Bereitstellung eines...