>  기사  >  데이터 베이스  >  Python을 사용하여 Schema 방식을 운용하는 MySQL 데이터베이스에 대한 자세한 설명

Python을 사용하여 Schema 방식을 운용하는 MySQL 데이터베이스에 대한 자세한 설명

小云云
小云云원래의
2017-12-08 09:52:501636검색

스키마란 무엇인가요?

어떤 애플리케이션을 만들든 사용자 입력을 처리하는 한 원칙은 하나입니다. 사용자의 입력 데이터를 절대 신뢰하지 마세요. 즉, 웹 개발에서 입력 데이터는 일반적으로 JSON 형식으로 백엔드 API에 전송되며, API는 입력 데이터를 확인해야 합니다. 일반적으로 많은 판단과 다양한 ifs를 추가하므로 코드가 매우 보기 흉해집니다. 사용자 데이터를 확인하는 더 우아한 방법이 있습니까? 스키마가 유용합니다. 이 글은 주로 Python을 사용하여 MySQL 데이터베이스 설계에서 스키마를 작동하는 방법에 대한 자세한 설명을 소개합니다. 도움이 필요한 친구들을 위해 여기에서 공유하겠습니다.

㈠ MySQLdb 부분

테이블 구조:

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)

데이터베이스 연결 모듈:

[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 인쇄 열 메타 데이터

[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. ) Execution()을 호출한 후 커서는 설명 속성을 설정해야 합니다
2.) 이는 열 이름, 유형, 표시 크기, 내부 크기, 정밀도, 범위 및 허용 여부를 나타내는 플래그 등 총 7개의 열이 있는 튜플입니다. null 값

[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 열 이름으로 열 값에 액세스

기본적으로 get 메서드에서 데이터베이스의 "행"으로 반환된 값은 튜플입니다.

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

커서클래스 속성을 사전으로 사용할 수 있습니다. Return

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 Alchemist

SQL에는 국제 표준이 있지만 안타깝게도 데이터베이스 제조업체마다 이러한 표준에 대해 서로 다른 해석을 하고 있으며, 그것들은 모두 자체적인 개인 구문 구현을 기반으로 하는 표준에 있습니다. 다양한 SQL "언어" 간의 차이점을 숨기기 위해 사람들은 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()

예 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)

예 2와 같은 도구를 개발했습니다. : 테이블 삭제

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

예제 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 기본값

은 비관적(DB 서버에서 제공하는 값)과 낙관적( SQLAlshemy에서 제공하는 값), 낙관적이고 나눌 수 있음: 삽입 및 업데이트

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)

㈢ Hidden Schema

데이터의 보안이 완전히 신뢰할 수 있는 개체에 노출되든, 이는 보안에 민감한 DBA에게 질문합니다. 위험을 감수하지 않겠습니다. 더 나은 방법은 스키마 구조를 최대한 숨기고 사용자가 입력한 데이터의 무결성을 확인하는 것입니다. 이는 운영 및 유지 관리 비용을 어느 정도 증가시키지만 안전에 있어서는 사소한 문제가 아닙니다.

여기서 문제를 설명하기 위한 명령줄 도구를 개발합니다

요구 사항: 테이블 구조 숨기기, 동적 쿼리 구현 및 결과를 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&#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 
......<此处省略大部分输出>......

코드를 참조하세요

#!/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()

관련 추천:

데이터베이스의 테이블과 스키마의 차이점에 대한 자세한 설명

MySQL의 information_schema에 대한 자세한 소개

MySQL 분산 클러스터 MyCAT (2) 스키마 코드에 대한 자세한 설명

위 내용은 Python을 사용하여 Schema 방식을 운용하는 MySQL 데이터베이스에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.