Heim  >  Artikel  >  Datenbank  >  Detaillierte Erläuterung der MySQL-Datenbank mit Python zum Betrieb der Schema-Methode

Detaillierte Erläuterung der MySQL-Datenbank mit Python zum Betrieb der Schema-Methode

小云云
小云云Original
2017-12-08 09:52:501667Durchsuche

Was ist Schema?

Egal welche Anwendung wir erstellen, solange wir mit Benutzereingaben umgehen, gibt es ein Prinzip: Vertrauen Sie niemals den Eingabedaten des Benutzers. Das bedeutet, dass wir Benutzereingaben streng überprüfen müssen. Bei der Webentwicklung werden Eingabedaten im Allgemeinen in JSON-Form an die Back-End-API gesendet, und die API muss die Eingabedaten überprüfen. 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? Schema ist praktisch. In diesem Artikel wird hauptsächlich die Methode zur Verwendung von Python zum Betreiben von Schema im MySQL-Datenbankdesign vorgestellt. Ich werde es hier als Referenz für Freunde teilen, die es benötigen.

㈠ MySQLdb-Teil

Tabellenstruktur:

mysql> use sakila; 
mysql> desc actor; 
+-------------+----------------------+------+-----+-------------------+-----------------------------+ 
| Field    | Type         | Null | Key | Default      | Extra            | 
+-------------+----------------------+------+-----+-------------------+-----------------------------+ 
| actor_id  | smallint(5) unsigned | NO  | PRI | NULL       | auto_increment       | 
| first_name | varchar(45)     | NO  |   | NULL       |               | 
| last_name  | varchar(45)     | NO  | MUL | NULL       |               | 
| last_update | timestamp      | NO  |   | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | 
+-------------+----------------------+------+-----+-------------------+-----------------------------+ 
4 rows in set (0.00 sec)

Datenbankverbindungsmodul:

[root@DataHacker ~]# cat dbapi.py 
#!/usr/bin/env ipython 
#coding = utf-8 
#Author: linwaterbin@gmail.com 
#Time: 2014-1-29 
 
import MySQLdb as dbapi 
 
USER = 'root' 
PASSWD = 'oracle' 
HOST = '127.0.0.1' 
DB = 'sakila' 
 
conn = dbapi.connect(user=USER,passwd=PASSWD,host=HOST,db=DB)

1 Spaltenmetadaten drucken

[root@DataHacker ~]# cat QueryColumnMetaData.py 
#!/usr/bin/env ipython 
 
from dbapi import * 
 
cur = conn.cursor() 
statement = """select * from actor limit 1""" 
cur.execute(statement) 
 
print "output column metadata....." 
print 
for record in cur.description: 
  print record 
 
cur.close() 
conn.close()

1.) Nach dem Aufruf vonexecute() sollte der Cursor sein Beschreibungsattribut setzen
2.) Es handelt sich um ein Tupel mit insgesamt 7 Spalten: Spaltenname , Typ, Anzeigegröße, interne Größe, Genauigkeit, Bereich und ein Flag, das angibt, ob Nullwerte akzeptiert werden sollen

[root@DataHacker ~]# chmod +x QueryColumnMetaData.py 
[root@DataHacker ~]# ./QueryColumnMetaData.py 
output column metadata..... 
 
('actor_id', 2, 1, 5, 5, 0, 0) 
('first_name', 253, 8, 45, 45, 0, 0) 
('last_name', 253, 7, 45, 45, 0, 0) 
('last_update', 7, 19, 19, 19, 0, 0)

2 Zugriff Spaltenwerte nach Spaltenname

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

In [1]: from dbapi import * 
In [2]: cur = conn.cursor() 
In [3]: v_sql = "select actor_id,last_name from actor limit 2" 
In [4]: cur.execute(v_sql) 
Out[4]: 2L 
In [5]: results = cur.fetchone() 
In [6]: print results[0] 
58 
In [7]: print results[1] 
AKROYD

Wir können das Cursorclass-Attribut verwenden, um

In [2]: import MySQLdb.cursors 
In [3]: import 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) 
Out[7]: 2L 
In [8]: results = cur.fetchone() 
In [9]: print results['actor_id'] 
58 
In [10]: print results['last_name'] 
AKROYD

㈡ SQLAlchemy--SQL zurückzugeben Alchemist

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

SQLAlchemy-Verbindungsmodul:

[root@DataHacker Desktop]# cat sa.py 
import sqlalchemy as sa 
engine = sa.create_engine('mysql://root:oracle@127.0.0.1/testdb',pool_recycle=3600) 
metadata = sa.MetaData()

Beispiel 1: Tabellendefinition

In [3]: t = Table('t',metadata, 
   ...:        Column('id',Integer), 
   ...:        Column('name',VARCHAR(20)), 
   ...:        mysql_engine='InnoDB', 
   ...:        mysql_charset='utf8' 
   ...:       ) 
 
In [4]: t.create(bind=engine)

Beispiel 2: Tabellenlöschung

有2种方式,其一: 
In [5]: t.drop(bind=engine,checkfirst=True)  
另一种是: 
In [5]: metadata.drop_all(bind=engine,checkfirst=True),其中可以借助tables属性指定要删除的对象

Beispiel 3: 5 Arten von Einschränkungen

3 .1 primary key 
下面2种方式都可以,一个是列级,一个是表级 
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 = Table('t_pk_01',metadata,Column('id',Integer),Column('name',VARCHAR(20)),PrimaryKeyConstraint('id','name',name='prikey')) 
In [10]: t_pk_tb.create(bind=engine) 
3.2 Foreign Key 
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 = Table('t_fk_tb',metadata,Column('col1',Integer),Column('col2',VARCHAR(10)),ForeignKeyConstraint(['col1','col2'],['t_pk.id','t_pk.name'])) 
In [16]: t_fk_tb.create(bind=engine) 
3.3 unique 
In [17]: t_uni = Table('t_uni',metadata,Column('id',Integer,unique=True)) 
In [18]: t_uni.create(bind=engine) 
In [19]: t_uni_tb = Table('t_uni_tb',metadata,Column('col1',Integer),Column('col2',VARCHAR(10)),UniqueConstraint('col1','col2')) 
In [20]: t_uni_tb.create(bind=engine) 
3.4 check 
   虽然能成功,但MySQL目前尚未支持check约束。这里就不举例了。 
3.5 not null 
In [21]: t_null = Table('t_null',metadata,Column('id',Integer,nullable=False)) 
In [22]: t_null.create(bind=engine)

4 Standardwerte

ist in zwei Kategorien unterteilt: Pessimismus (vom DB-Server bereitgestellter Wert) und Optimismus (vom SQLAlshemy bereitgestellter Wert). Optimismus kann unterteilt werden in: Einfügen und Aktualisieren

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

㈢ Schema ausblenden

Ob die Sicherheit der Daten einem völlig vertrauenswürdigen Objekt ausgesetzt ist, ist dies ist der Schlüssel für jeden mit einem Risiko, das kein sicherheitsbewusster DBA eingehen würde. Eine bessere Möglichkeit besteht darin, die Schemastruktur so weit wie möglich zu verbergen und die Integrität der vom Benutzer eingegebenen Daten zu überprüfen. Dies erhöht zwar die Betriebs- und Wartungskosten, ist jedoch aus Sicherheitsgründen keine triviale Angelegenheit.


Hier entwickeln wir ein Befehlszeilentool, um dieses Problem zu veranschaulichen


Anforderungen: Tabellenstruktur ausblenden, dynamische Abfrage implementieren und die Ergebnisse für die MySQL-G-Ausgabe simulieren

版本: 
[root@DataHacker ~]# ./sesc.py --version 
1.0 
查看帮助: 
[root@DataHacker ~]# ./sesc.py -h 
Usage: sesc.py [options] <arg1> <arg2> [<arg3>...] 
Options: 
 --version       show program&#39;s version number and exit 
 -h, --help      show this help message and exit 
 -q TERM        assign where predicate 
 -c COL, --column=COL assign query column 
 -t TABLE       assign query table 
 -f, --format     -f must match up -o 
 -o OUTFILE      assign output file 
我们要的效果: 
[root@DataHacker ~]# ./sesc.py -t actor -c last_name -q s% -f -o output.txt 
[root@DataHacker ~]# cat output.txt 
************ 1 row ******************* 
actor_id: 180 
first_name: JEFF 
last_name: SILVERSTONE 
last_update: 2006-02-15 04:34:33 
************ 2 row ******************* 
actor_id: 195 
first_name: JAYNE 
last_name: SILVERSTONE 
last_update: 2006-02-15 04:34:33 
......<此处省略大部分输出>......

Bitte beachten Sie den Code

#!/usr/bin/env python
import optparse
from dbapi import *

#构造OptionParser实例,配置期望的选项
parser = optparse.OptionParser(usage="%prog [options] <arg1> <arg2> [<arg3>...]",version=&#39;1.0&#39;,)
#定义命令行选项,用add_option一次增加一个
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="assign query column")
parser.add_option("-t",action="store",type="string",dest="table",help="assign query table")
parser.add_option("-f","--format",action="store_true",dest="format",help="-f must match up -o")
parser.add_option("-o",action="store",type="string",dest="outfile",help="assign output file")
#解析命令行
options,args = parser.parse_args()
#把上述dest值赋给我们自定义的变量
table = options.table
column = options.col
term = options.term
format = options.format
#实现动态读查询
statement = "select * from %s where %s like &#39;%s&#39;"%(table,column,term)
cur = conn.cursor()
cur.execute(statement)
results = cur.fetchall()
#模拟 \G 输出形式
if format is True:
 columns_query = "describe %s"%(table)
 cur.execute(columns_query)
 heards = cur.fetchall()
 column_list = []
 for record in heards:
  column_list.append(record[0])
 output = ""
 count = 1
 for record in results:
  output = output + "************ %s row ************\n\n"%(count)
  for field_no in xrange(0, len(column_list)):
   output = output + column_list[field_no]+ ": " + str(record[field_no]) + "\n"
  output = output + "\n"
  count = count + 1
else:
 output = []
 for record in xrange(0,len(results)):
  output.append(results[record])
 output = &#39;&#39;.join(output)
#把输出结果定向到指定文件
if options.outfile:
 outfile = options.outfile
 with open(outfile,&#39;w&#39;) as out:
  out.write(output)
else:
 print output
#关闭游标与连接
conn.close()
cur.close()

Verwandte Empfehlungen:

Detaillierte Erläuterung des Unterschieds zwischen Tabelle und Schema in der Datenbank

Detaillierte Einführung in information_schema in MySQL

Verteilter MySQL-Cluster MyCAT (2) Detaillierte Erläuterung des Schemacodes

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der MySQL-Datenbank mit Python zum Betrieb der Schema-Methode. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn