溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MySQL數(shù)據(jù)庫通過Python操作Schema的詳細(xì)步驟

發(fā)布時間:2020-05-12 16:40:16 來源:億速云 閱讀:265 作者:三月 欄目:MySQL數(shù)據(jù)庫

本文主要給大家簡單講講MySQL數(shù)據(jù)庫通過Python操作Schema的詳細(xì)步驟,相關(guān)專業(yè)術(shù)語大家可以上網(wǎng)查查或者找一些相關(guān)書籍補(bǔ)充一下,這里就不涉獵了,我們就直奔主題吧,希望MySQL數(shù)據(jù)庫通過Python操作Schema的詳細(xì)步驟這篇文章可以給大家?guī)硪恍嶋H幫助。                                                          

㈠ MySQLdb部分

表結(jié)構(gòu):

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)

數(shù)據(jù)庫連接模塊:

[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 打印列的元數(shù)據(jù)

[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.)調(diào)用execute()之后,cursor應(yīng)當(dāng)設(shè)置其description屬性
2.)是個tuple,共7列:列名、類型、顯示大小、內(nèi)部大小、精度、范圍以及一個是否接受null值的標(biāo)記

[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 通過列名訪問列值

默認(rèn)情況下,獲取方法從數(shù)據(jù)庫作為"行"返回的值是元組

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

我們能夠借助cursorclass屬性來作為字典返回

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煉金術(shù)師

雖然SQL有國際標(biāo)準(zhǔn),但遺憾的是,各個數(shù)據(jù)庫廠商對這些標(biāo)準(zhǔn)的解讀都不一樣,并且都在標(biāo)準(zhǔn)的基礎(chǔ)上實現(xiàn)了各自的私有語法。為了隱藏不同SQL“方言”之間到區(qū)別,人們開發(fā)了諸如SQLAlchemy之類的工具

SQLAlchemy連接模塊:

[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()

example 1:表定義

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)

example 2:表刪除

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

example 3: 5種約束

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 默認(rèn)值

分2類:悲觀(值由DB Server提供)和樂觀(值由SQLAlshemy提供),其中樂觀又可分:insert和update

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

數(shù)據(jù)的安全是否暴露在完全可信任的對象面前,這是任何有安全意識的DBA都不會去冒的風(fēng)險。比較好的方式是盡可能隱藏Schema結(jié)構(gòu)并驗證用戶輸入的數(shù)據(jù)完整性,這在一定程度上雖然增加了運(yùn)維成本,但安全無小事。

這里借助開發(fā)一個命令行工具來闡述該問題

需求:隱藏表結(jié)構(gòu),實現(xiàn)動態(tài)查詢,并將結(jié)果模擬mysql \G輸出

版本: 
[root@DataHacker ~]# ./sesc.py --version 
1.0 
查看幫助: 
[root@DataHacker ~]# ./sesc.py -h 
Usage: sesc.py [options] <arg1> <arg2> [<arg3>...] 
Options: 
 --version       show program'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 
......<此處省略大部分輸出>......

請看代碼

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

#構(gòu)造OptionParser實例,配置期望的選項
parser = optparse.OptionParser(usage="%prog [options] <arg1> <arg2> [<arg3>...]",version='1.0',)
#定義命令行選項,用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
#實現(xiàn)動態(tài)讀查詢
statement = "select * from %s where %s like '%s'"%(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 = ''.join(output)
#把輸出結(jié)果定向到指定文件
if options.outfile:
 outfile = options.outfile
 with open(outfile,'w') as out:
  out.write(output)
else:
 print output
#關(guān)閉游標(biāo)與連接
conn.close()
cur.close()

MySQL數(shù)據(jù)庫通過Python操作Schema的詳細(xì)步驟就先給大家講到這里,對于其它相關(guān)問題大家想要了解的可以持續(xù)關(guān)注我們的行業(yè)資訊。我們的板塊內(nèi)容每天都會捕捉一些行業(yè)新聞及專業(yè)知識分享給大家的。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI