MySQLデータベース設計:Pythonを使ったスキーマ操作方法の詳しい解説

MySQLデータベース設計:Pythonを使ったスキーマ操作方法の詳しい解説

矢が放たれる前に、弓は矢にささやきました。「お前の自由は私のものだ。」スキーマは矢のようなもので、弓は Python のようなものです。Python を選択することが、スキーマの最大の自由です。そして自由は、自分自身をより良くするための機会であるべきです。

スキーマとは何ですか?

どのようなアプリケーションを作成する場合でも、ユーザー入力を処理する限り、ユーザーの入力データを決して信頼しないという原則があります。つまり、ユーザー入力を厳密に検証する必要があります。Web アプリケーションを開発する場合、入力データは通常、JSON 形式でバックエンド API に送信され、API は入力データを検証する必要があります。通常、多くの判断とさまざまな if を追加するため、コードが非常に醜くなります。ユーザー データを検証するよりエレガントな方法はありますか?ここで Schema が役に立ちます。

(Ⅰ)MySQLdb部分

テーブル構造:

mysql> sakila を使用します。 
mysql> desc アクター; 
+-------------+----------------------+------+-----+-------------------+----------------------------+ 
| フィールド | タイプ | Null | キー | デフォルト | 追加 | 
+-------------+----------------------+------+-----+-------------------+----------------------------+ 
| 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 | タイムスタンプ | NO | | CURRENT_TIMESTAMP | 更新時 CURRENT_TIMESTAMP | 
+-------------+----------------------+------+-----+-------------------+----------------------------+ 
セット内の 4 行 (0.00 秒)

データベース接続モジュール:

[root@DataHacker ~]# cat dbapi.py 
#!/usr/bin/env ipython 
#コーディング = utf-8 
#著者: [email protected] 
#時間: 2014-1-29 
 
MySQLdbをdbapiとしてインポートする 
 
ユーザー = 'root' 
パスワード = 'oracle' 
ホスト = '127.0.0.1' 
DB = 'サキラ' 
 
conn = dbapi.connect(user=USER、passwd=PASSWD、host=HOST、db=DB)

1 列のメタデータを印刷する

[root@DataHacker ~]# cat QueryColumnMetaData.py 
#!/usr/bin/env ipython 
 
dbapi インポートから * 
 
cur = conn.cursor() 
ステートメント = """アクター制限 1 から * を選択""" 
cur.execute(ステートメント) 
 
「出力列のメタデータ.....」を印刷します 
印刷 
cur.description のレコードの場合: 
  印刷記録 
 
cur.close() 
接続を閉じる()

1.) execute() を呼び出した後、カーソルは説明属性を設定する必要があります。
2.) 列名、タイプ、表示サイズ、内部サイズ、精度、範囲、および null 値が受け入れられるかどうかを示すフラグの 7 つの列を持つタプルです。

[root@DataHacker ~]# chmod +x QueryColumnMetaData.py 
[root@DataHacker ~]# ./QueryColumnMetaData.py 
出力列のメタデータ..... 
 
('俳優ID', 2, 1, 5, 5, 0, 0) 
('first_name', 253, 8, 45, 45, 0, 0) 
('姓', 253, 7, 45, 45, 0, 0) 
('最終更新'、7、19、19、19、0、0)

2 列名による列値へのアクセス

デフォルトでは、getメソッドによってデータベースから「行」として返される値はタプルです。

[1]: dbapiインポートから* 
[2]では: cur = conn.cursor() 
In [3]: v_sql = "俳優制限2からactor_id、last_nameを選択" 
[4]では: cur.execute(v_sql) 
アウト[4]: 2L 
[5]では: 結果 = cur.fetchone() 
In [6]: 結果を印刷する[0] 
58 
In [7]: 結果を印刷する[1] 
アクロイド

カーソルクラス属性を使用して辞書として返すことができます

[2]: MySQLdb.cursorsをインポートする 
[3]: MySQLdbをインポートする 
[4]では:conn = MySQLdb.connect(user='root',passwd='oracle',host='127.0.0.1',db='sakila',cursorclass=MySQLdb.cursors.DictCursor) 
[5]では: cur = conn.cursor() 
In [6]: v_sql = "俳優制限2からactor_id、last_nameを選択" 
[7]では: cur.execute(v_sql) 
アウト[7]: 2L 
[8]では: 結果 = cur.fetchone() 
In [9]: 結果を印刷['actor_id'] 
58 
In [10]: 結果を印刷['last_name'] 
アクロイド

2. SQLAlchemy - SQL 錬金術師

SQL には国際標準がありますが、残念ながら、各データベース ベンダーはこれらの標準をそれぞれ異なる方法で解釈し、標準に基づいて独自の構文を実装しています。異なるSQL「方言」間の違いを隠すために、SQLAlchemyなどのツールが開発されました。

SQLAlchemy 接続モジュール:

[root@DataHacker Desktop]# cat sa.py 
sqlalchemy を sa としてインポートします 
エンジン = sa.create_engine('mysql://root:[email protected]/testdb',pool_recycle=3600) 
メタデータ = sa.MetaData()

例1: テーブル定義

[3]では: t = Table('t',メタデータ, 
   ...: 列('id',整数), 
   ...: 列('name',VARCHAR(20)), 
   ...: mysql_engine='InnoDB', 
   ...: mysql_charset='utf8' 
   ...: ) 
 
[4]では: ​​t.create(bind=engine)

例2: テーブルの削除

方法は 2 つあり、そのうちの 1 つは次のとおりです。 
[5]では: t.drop(bind=engine,checkfirst=True)  
もう一つは: 
[5]: metadata.drop_all(bind=engine,checkfirst=True)では、tables属性を使用して削除するオブジェクトを指定できます。

例3: 5つの制約

3.1 主キー 
次の2つの方法はどちらも受け入れられ、1つは列レベル、もう1つはテーブルレベルです。[7]では、t_pk_col = Table('t_pk_col',metadata,Column('id',Integer,primary_key=True),Column('name',VARCHAR(20))) 
[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')) 
[10]: t_pk_tb.create(bind=engine) 
3.2 外部キー 
[13]では: t_fk = Table('t_fk',metadata,Column('id',Integer,ForeignKey('t_pk.id'))) 
[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'])) 
[16]: t_fk_tb.create(bind=engine) 
3.3 ユニーク 
[17]において: t_uni = Table('t_uni',metadata,Column('id',Integer,unique=True)) 
[18]: t_uni.create(bind=engine) 
In [19]: t_uni_tb = Table('t_uni_tb',メタデータ,列('col1',整数),列('col2',VARCHAR(10)),UniqueConstraint('col1','col2')) 
[20]: t_uni_tb.create(bind=engine) 
3.4 チェック 
   動作しますが、MySQL は現在チェック制約をサポートしていません。ここでは例は挙げません。 
3.5 ヌルではない 
[21]では: t_null = Table('t_null',metadata,Column('id',Integer,nullable=False)) 
[22]では: t_null.create(bind=engine)

4 デフォルト値

悲観的(DBサーバーによって提供される値)と楽観的(SQLAlshemyによって提供される値)の2つのカテゴリがあり、楽観的は挿入と更新に分けられます。

4.1 例: 挿入 
[23]では: t_def_inser = Table('t_def_inser',metadata,Column('id',Integer),Column('name',VARCHAR(10),server_default='cc')) 
[24]: t_def_inser.create(bind=engine) 
3.2 例: 更新 
In [25]: t_def_upda = Table('t_def_upda',metadata,Column('id',Integer),Column('name',VARCHAR(10),server_onupdate='DataHacker')) 
[26]: t_def_upda.create(bind=engine) 
3.3 例: 受動態  
[27]では: t_def_pass = Table('t_def_pass',metadata,Column('id',Integer),Column('name',VARCHAR(10),DefaultClause('cc'))) 
[28]: t_def_pass.create(bind=engine)

3. スキーマを非表示にする

データのセキュリティが完全に信頼できるオブジェクトに公開されるかどうかは、セキュリティを重視する DBA が負うことのないリスクです。より良いアプローチは、スキーマ構造を可能な限り隠し、ユーザーが入力したデータの整合性を検証することです。これにより、運用および保守コストがある程度増加しますが、セキュリティは最も重要です。

ここでは、コマンドラインツールの開発を使用してこの問題を説明します。

要件: テーブル構造を非表示にし、動的クエリを実装し、結果のmysql \G出力をシミュレートする

バージョン: 
[root@DataHacker ~]# ./sesc.py --version 
1.0 
ヘルプを表示: 
[root@DataHacker ~]# ./sesc.py -h 
使用方法: sesc.py [オプション] <arg1> <arg2> [<arg3>...] 
オプション: 
 --version プログラムのバージョン番号を表示して終了する 
 -h, --help このヘルプメッセージを表示して終了します 
 -q TERM 述語の割り当て 
 -c COL, --column=COL クエリ列を割り当てる 
 -t TABLE クエリテーブルを割り当てる 
 -f、--format -f は -o と一致する必要があります 
 -o OUTFILE 出力ファイルを割り当てる 
望む効果: 
[root@DataHacker ~]# ./sesc.py -t アクター -c 姓 -qs% -f -o 出力.txt 
[root@DataHacker ~]# cat output.txt 
************ 1行 ******************** 
俳優ID: 180 
ファーストネーム: ジェフ 
姓: シルバーストーン 
最終更新日: 2006-02-15 04:34:33 
************ 2行目 ******************** 
俳優ID: 195 
ファーストネーム: ジェーン 
姓: シルバーストーン 
最終更新日: 2006-02-15 04:34:33 
......<出力の大部分は省略>......

コードをご覧ください

#!/usr/bin/env python
optparse をインポートする
dbapi インポートから *

#OptionParserインスタンスを構築し、期待されるオプションを設定します parser = optparse.OptionParser(usage="%prog [options] <arg1> <arg2> [<arg3>...]",version='1.0',)
#add_option を使用してコマンドライン オプションを 1 つずつ追加して定義します。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="クエリ列の割り当て")
parser.add_option("-t",action="store",type="string",dest="table",help="クエリテーブルの割り当て")
parser.add_option("-f","--format",action="store_true",dest="format",help="-f は -o と一致する必要があります")
parser.add_option("-o",action="store",type="string",dest="outfile",help="出力ファイルの割り当て")
#コマンドラインオプションを解析します。args = parser.parse_args()
#上記のdest値をカスタム変数table = options.tableに割り当てます
列 = オプション.col
用語 = オプション.用語
フォーマット = オプション.フォーマット
# 動的読み取りクエリを実装します。ステートメント = "select * from %s where %s like '%s'"%(table,column,term)
cur = conn.cursor()
cur.execute(ステートメント)
結果 = cur.fetchall()
#format が True の場合、\G 出力形式をシミュレートします。
 columns_query = "%s を記述する"%(テーブル)
 cur.execute(列クエリ)
 聞いた = cur.fetchall()
 列リスト = []
 記録のために:
  列リストに追加(レコード[0])
 出力 = ""
 カウント = 1
 結果の記録:
  出力 = 出力 + "************ %s 行 ************\n\n"%(count)
  xrange(0, len(column_list))内のfield_noの場合:
   出力 = 出力 + 列リスト[フィールド番号]+ ": " + str(レコード[フィールド番号]) + "\n"
  出力 = 出力 + "\n"
  カウント = カウント + 1
それ以外:
 出力 = []
 xrange(0,len(results))内のレコードの場合:
  output.append(結果[レコード])
 出力 = ''.join(出力)
#options.outfile の場合、出力結果を指定されたファイルに送信します:
 出力ファイル = オプション.出力ファイル
 open(outfile,'w') を出力として:
  out.write(出力)
それ以外:
 印刷出力
#カーソルと接続を閉じる conn.close()
cur.close()

要約する

以上がMySQLデータベース設計におけるPythonを使ったスキーマ操作方法の詳細解説の記事の内容です。皆様のお役に立てれば幸いです。 Python タイマーのサンプルコード、Python デジタル画像生成コードの共有など、ぜひご参照ください。ご質問がある場合は、いつでもメッセージを残してください。編集者が適時に返信します。ぜひメッセージを残して議論してください。

以下もご興味があるかもしれません:
  • Pythonはスキーマを通じてデータ検証を実装する
  • PythonはHiveデータテーブルのスキーマサンプルコードをエクスポートします
  • Python を使用して HDFS 上の parquet ファイルを読み取る方法
  • Python で XML 形式のファイルを TXT ファイルに変換する問題を解決する (xml.etree メソッド)
  • Pythonで辞書をJSONファイルとして書き込む方法
  • Python 標準ライブラリ zipfile を使用して圧縮パッケージにフォルダーを追加する方法
  • Python ファイル処理 - ファイルの読み取りと書き込みの詳細な説明
  • Pythonを使用してスキーマを定義し、Parquetファイルの詳細を生成します

<<:  JavaScript演算子の使用に関するヒントをいくつか共有します

>>:  ライフゲームの JavaScript 実装

推薦する

MySQL 単一テーブルクエリの例の詳細な説明

1. データを準備するこのテーブルでは次の操作が実行されます 学生テーブルを作成 ( id int ...

21 の MySQL 標準化および最適化のベスト プラクティス!

序文良い習慣はすべて宝物です。この記事は、SQL の後悔の治療法、SQL パフォーマンスの最適化、S...

Select はダブルクリック dbclick イベントをサポートしていません

XML/HTML コードコンテンツをクリップボードにコピー< div クラス= "c...

MySQLスローログクエリの詳細な説明

遅いログクエリ機能スロー ログ クエリの主な機能は、設定された時間しきい値を超える SQL ステート...

Zabbix による VMware Exsi ホストの監視のグラフィカルな手順

1. 仮想化 vcenter に入り、ブラウザでログインし (クライアントは設定する場所を見つけませ...

React 国際化 react-i18next の詳細な説明

導入react-i18next は、 i18nextをベースにした強力な国際化フレームワークです。 ...

vue+tsは要素のマウスドラッグの効果を実現します

この記事の例では、要素のマウスドラッグ効果を実現するためのvue+tsの具体的なコードを参考までに共...

HTML チュートリアル: HTML 水平線分

<br />このタグを使用すると、画面上に水平線を表示して、ページのさまざまな部分を区切...

VMware10 での CentOS 7 のインストールと設定のチュートリアル

Ubuntu が今日のデスクトップ ユーザーの間で最も人気のある Linux オペレーティング シス...

mysql インストーラ コミュニティ 8.0.16.0 のインストールと構成のグラフィック チュートリアル

mysqlインストーラコミュニティ8.0.16.0インストールグラフィックチュートリアル、参考までに...

HTML テーブルのオーバーフローの解決方法

テーブルが広い場合は、あふれてしまう可能性があります。たとえば、左と右の 2 つの div がありま...

LinuxサーバのSSHクラッキング防止方法(推奨)

1. Linuxサーバーは、/etc/hosts.denyを設定して、相手のIPがSSH経由でサー...

MySQL の高度な機能 - データ テーブル パーティショニングの概念とメカニズムの詳細な説明

目次パーティション分割メカニズムSELECTクエリINSERT操作DELETE操作更新操作パーティシ...

CSS で美しい時計アニメーション効果を実装するためのサンプルコード

仕事を探しています!!!事前準備:まず、このアニメーションは、以前のローディングアニメーションとクー...