矢が放たれる前に、弓は矢にささやきました。「お前の自由は私のものだ。」スキーマは矢のようなもので、弓は 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() を呼び出した後、カーソルは説明属性を設定する必要があります。 [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 デジタル画像生成コードの共有など、ぜひご参照ください。ご質問がある場合は、いつでもメッセージを残してください。編集者が適時に返信します。ぜひメッセージを残して議論してください。 以下もご興味があるかもしれません:
|
<<: JavaScript演算子の使用に関するヒントをいくつか共有します
1. データを準備するこのテーブルでは次の操作が実行されます 学生テーブルを作成 ( id int ...
序文良い習慣はすべて宝物です。この記事は、SQL の後悔の治療法、SQL パフォーマンスの最適化、S...
XML/HTML コードコンテンツをクリップボードにコピー< div クラス= "c...
遅いログクエリ機能スロー ログ クエリの主な機能は、設定された時間しきい値を超える SQL ステート...
1. 仮想化 vcenter に入り、ブラウザでログインし (クライアントは設定する場所を見つけませ...
導入react-i18next は、 i18nextをベースにした強力な国際化フレームワークです。 ...
データベースバージョン: mysql> select version(); +--------...
この記事の例では、要素のマウスドラッグ効果を実現するためのvue+tsの具体的なコードを参考までに共...
<br />このタグを使用すると、画面上に水平線を表示して、ページのさまざまな部分を区切...
Ubuntu が今日のデスクトップ ユーザーの間で最も人気のある Linux オペレーティング シス...
mysqlインストーラコミュニティ8.0.16.0インストールグラフィックチュートリアル、参考までに...
テーブルが広い場合は、あふれてしまう可能性があります。たとえば、左と右の 2 つの div がありま...
1. Linuxサーバーは、/etc/hosts.denyを設定して、相手のIPがSSH経由でサー...
目次パーティション分割メカニズムSELECTクエリINSERT操作DELETE操作更新操作パーティシ...
仕事を探しています!!!事前準備:まず、このアニメーションは、以前のローディングアニメーションとクー...