python3ウェブクローラ戦闘-32、データ保存:保存するリレーショナルデータベース:MySQLの

リレーショナルモデルデータベース、リレーショナルモデルに基づいて、リレーショナルデータベースが保持する二次元の表であるので、記憶テーブルは、ランクから構成されていて、各列がフィールドであり、各行がレコードです。表は、エンティティのコレクションとして見ることができますが、反映するために、テーブルとテーブル間の関係を必要とするエンティティ間のリンクは、関係があり、主キーと外部キーの関係、データベースの複数のテーブル、などがあり、データベース。

このようようにSQLiteのは、MySQL、OracleやSQL Serverの、DB2、およびリレーショナルデータベースの様々なものがあります。

このセクションでは、次のpython3 MySQLのストレージを導入します。

Python2では、ライブラリを使用することをお勧めしますので、ここで、接続のMySQLライブラリは、ほとんどのMySQLdbを使用しますが、このライブラリは公式のpython3をサポートしていませんPyMySQLです。

このセクションでは、操作方法PyMySQL MySQLデータベースを説明します。

1.準備

このセクションを開始する前に、あなたはMySQLデータベースと実行をインストールするだけでなく、PyMySQLライブラリをインストールする必要があり、インストールされていない場合は、あなたが最初の章のインストール手順を参照することができていることを確認してください。

2. Connectデータベース

ここでは、第1のポートは、我々はPyMySQLはそれを接続してから、新しいMySQLデータベースを作成して使用3306、で実行し、ローカルで実行されている現在のMySQLはrootユーザのパスワードが123456であると呼ばれることが想定されているデータベースに接続しよう、と呼ばれるスパイダー、としては次のとおりです。

import pymysql

db = pymysql.connect(host='localhost',user='root', password='123456', port=3306)
cursor = db.cursor()
cursor.execute('SELECT VERSION()')
data = cursor.fetchone()
print('Database version:', data)
cursor.execute("CREATE DATABASE spiders DEFAULT CHARACTER SET utf8")
db.close()
Python资源分享qun 784758214 ,内有安装包,PDF,学习视频,这里是Python学习者的聚集地,零基础,进阶,都欢迎

結果:

Database version: ('5.6.22',)

MySQLがローカルで実行されているので、入ってくるが、ローカルホスト、リモートMySQL実行している場合、パスであるため、ここでは(MySQLの接続オブジェクトの接続PyMySQLによって)メソッドの宣言は、ここでは、IPでのMySQLを実行しているホストを渡す必要がありますそのパブリックIPアドレスに変換し、デフォルトのポートであるその後のユーザパラメータ、すなわち、ユーザ名、パスワード、すなわちパスワード、ポート3306。

接続が成功した後、我々はまず、我々は適切なSQL文を実行するために()メソッドを実行使用して、2つのSQLを実行し、たとえば、カーソルを使用して、SQL文を実行するためにMySQLの操作カーソルを取得するために、カーソル()メソッドを呼び出す必要がありますMySQLのSQL文は、それがバージョン番号となっている、現在のバージョンを取得し、最初のデータを取得する方法)(fetchoneを呼び出すことで、我々はまた、データベース名は、デフォルトのエンコーディングがUTF-8であるスパイダーと呼ばれるデータベースの作成を行い、この文は、クエリではないので、正常データベースのスパイダーを作成した後、私たちは、私たちはその後の操作のために、このデータベースを使用します、直接実行しました。

3.テーブルを作成します。

一般に、上記の操作は、我々だけではもちろん、一度だけ実行する必要があるデータベースを作成するために、我々はこのデータベース操作上で動作しているので、我々はまた、手動で、データベースを作成することができるので、後で直接接続のMySQLの導入は、現在の指定しますデータベーススパイダーは、すべての操作は、クモのデータベース内で実行されています。

そこでここではMySQLの接続は、DBを指定するために追加のパラメータが必要です。

次に、我々は、ユーザのテーブルの学生を作成し、テーブルを作成するSQL文を実行し、新しいテーブルのデータを作成し、ここでは次のように構造化の3つのフィールドが、指定されました:

フィールド名 意味 タイプ
ID 学生ID VARCHAR
フルネーム VARCHAR
年齢 年齢 int型

次のようにサンプル・コードは、テーブルを作成します。

import pymysql

db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='spiders')
cursor = db.cursor()
sql = 'CREATE TABLE IF NOT EXISTS students (id VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, age INT NOT NULL, PRIMARY KEY (id))'
cursor.execute(sql)
db.close()
Python资源分享qun 784758214 ,内有安装包,PDF,学习视频,这里是Python学习者的聚集地,零基础,进阶,都欢迎

実行した後、我々は、フィールドが上記の3つの分野で、学生と呼ばれるデータテーブルを作成します。

もちろん、ここで私たちの指定された最も簡単ないくつかのフィールドのデモンストレーションとして、実際の爬虫類の過程で、私たちは、クロールの結果に基づいて、特定のフィールドを設計します。

4.データの挿入

次のステップは、我々はデータを解析された後、たとえば、データベースにデータを挿入することで、私たちは、学生情報の上昇を取ったところ、学生数はボブという名前の、20120001で、20歳、どのようにデータベースへのデータの一片例えば、コードは次のように

import pymysql

id = '20120001'
user = 'Bob'
age = 20

db = pymysql.connect(host='localhost', user='root', password='123456', port=3306, db='spiders')
cursor = db.cursor()
sql = 'INSERT INTO students(id, name, age) values(%s, %s, %s)'
try:
    cursor.execute(sql, (id, user, age))
    db.commit()
except:
    db.rollback()
db.close()

:ここでは、まず、私たちのような、建設に値値文字列の連結アプローチを使用していませんでしたSQL文を構築します

sql = 'INSERT INTO students(id, name, age) values(' + id + ', ' + name + ', ' + age + ')'

このような文言面倒かつ直感的ではないので、我々は直接実装する%sの文字形式を選択し、実行するSQL文に渡される最初のパラメータのいくつかのいくつかの書き込み%sの値は、我々のみ必要()メソッドがあり、うまくオーバー統一タプルと値転送値。

この文言は、トラブルを回避し、文字列の連結、また、紛争引用符の問題を回避することができました。

価値は、あなたがこの方法は、データ挿入のために利用可能である()dbオブジェクトをコミットを実行する必要があることを指摘した後、この方法では、操作を有効にするには、このメソッドを呼び出す必要が削除本当のステートメントは、データの挿入、更新のための方法を実行するためにデータベースに送信されますです。

次は失敗した場合、そのデータのロールバック、何が起こったかと同等のものを実行するために、ロールバック()を呼び出し、例外処理の層を追加します。

ここでは、それはどちらか、そのようなデータの一部を挿入すると、起こったり起こらなかったことが、あるトランザクション、データの一貫性を確保するためのトランザクション機構に関連する質問には、インサートの半分、どちらか完全に挿入されていない場合、または全体は存在しませんA挿入されていない、これはトランザクションと3つの他の特性、一貫性、分離性、耐久性に加えて、通常、ACID特性となる、アトミック・トランザクションです。

次のように要約:

プロパティ 説明
アトミック(不可分) トランザクションは、トランザクション内のすべての操作はどちらかが行うか行わないなどが、作業の不可分の単位です。
一貫性(一貫性) データベーストランザクションは、別の一貫した状態にある一貫した状態から変更する必要があります。一貫性とアトミック性は密接に関連しています。
絶縁(アイソレーション) トランザクションの実行は、他のトランザクション干渉することはできません。すなわち、操作および他の同時トランザクションが単離されると同時に実行される各トランザクションの間に互いに干渉することができないトランザクション内のデータを使用します。
持続性(耐久性) また、恒久(永続性)として知られ、永続的な、それはトランザクションがコミットされると、データベース内のデータを変更すると永久的でなければならないことを意味します。次の操作またはその他の障害は、それらに影響を持つべきではありません。

挿入、更新、および削除操作は、変更するデータベースの動作であり、変更操作はトランザクションとしてしなければならないので、これらの操作のための標準的な文言は次のとおりです。

try:
    cursor.execute(sql)
    db.commit()
except:
    db.rollback()

我々は、データの整合性を確保することができますこのように、ここにコミットだ()およびrollback()メソッドは、トランザクションの実現のためのサポートを提供することです。

フィールドが急激に増加場合さて、このような別のセックス性別の追加として、我々は、上記のデータの挿入操作を実現するためにSQLステートメントを構築することであることを理解、場所や不便があることは明らかです、我々は読んでSQLステートメントを構築する必要があります。

INSERT INTO students(id, name, age, gender) values(%s, %s, %s, %s)

対応するタプルは、パラメータを変更することが必要です。

(id, name, age, gender)

これは、多くの場合、我々が達成したい効果だけで私たちはちょうど罰金動的に変化する辞書を渡す必要があり、一般的な方法を行うことへの変更を必要としない方法を挿入することで、我々が望むもの、明らかではありません。たとえば、私たちは、このような辞書を構築します:

{
    'id': '20120001',
    'name': 'Bob',
    'age': 20
}
Python资源分享qun 784758214 ,内有安装包,PDF,学习视频,这里是Python学习者的聚集地,零基础,进阶,都欢迎

一般的な挿入方法を達成するように、その後、動的辞書に従って構成されたSQLステートメントが、タプルは、動的な構造です。そこでここでは、メソッドの再起草を挿入する必要があります。

data = {
    'id': '20120001',
    'name': 'Bob',
    'age': 20
}
table = 'students'
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))
sql = 'INSERT INTO {table}({keys}) VALUES ({values})'.format(table=table, keys=keys, values=values)
try:
   if cursor.execute(sql, tuple(data.values())):
       print('Successful')
       db.commit()
except:
    print('Failed')
    db.rollback()
db.close()

ここでは、テーブル名も変数テーブルとして定義され、データ変数として定義され、データ・ディクショナリの形で渡されました。その後、我々は、動的SQLステートメントを構築する必要があります。

まず、私たちはすることができ、単にデータのキー名を引き継ぐフィールド、ID、名前、年齢、に挿入され、その後、カンマで区切って構築する必要があります。したがって「」.join(data.keys())結果は、ID、名前、年齢、我々はプレースホルダとして%sの複数を構築する必要があり、そのような二つが存在する場合などのいくつかの構成のいくつかのフィールドは、ありますフィールドは、それが必要な構成の%s、%sで、長さの1%S、SO、ここで最初に定義されている配列[ '%S']は、乗算は[ '%s' は、 '%S' のように展開されています、 '%S']は、()メソッドは、最終的になるの%s、%sは、%sの参加を呼び出します。だから我々は、テーブル名、フィールド名、構築プレースホルダの文字列形式()メソッドを使用します、最後の文は、動的SQL構造がなりました。

INSERT INTO students(id, name, age) VALUES (%s, %s, %s)

最初のパラメータ、最後にexecute()メソッドSQL着信変数、タプルの鍵データ構成の第二の引数は、データを正常に挿入することができます。

我々はデータを挿入、および変更する辞書メソッドを渡す達成しているので、以降のSQL文は、挿入に行く必要はありません。

5.データの更新

データの更新は、実際にSQL文を実行し、最も簡単な方法は、構築し、SQL文を実行することです:

sql = 'UPDATE students SET age = %s WHERE name = %s'
try:
   cursor.execute(sql, (25, 'Bob'))
   db.commit()
except:
   db.rollback()
db.close()

ここでも、その後のパラメータのタプルの形式で渡す、execute()メソッドをexcute、プレースホルダのようにSQLで構成され、また、操作を実行するコミット()メソッドが実行されます。

あなたは、単純なデータの更新を行う場合は、この方法を使用することは完全に可能です。

しかし、プロセスを取り込む実際のデータでは、ほとんどの場合、データを挿入する必要がありますが、我々はすべての重複データがあることを懸念している、重複したデータがあった場合、我々は一般的なアプローチは、データではなく、繰り返しを更新することであることを願っています前述したようにデータが存在しない場合は繰り返し更新データは、データを挿入した場合だけでなく、行うことができます実際のデエンファシスを再実装するので、ここで私たちがここにいる、他のは、動的SQLの問題を構築し、時間を節約これは、値で柔軟な辞書をサポートしています。

data = {
    'id': '20120001',
    'name': 'Bob',
    'age': 21
}

table = 'students'
keys = ', '.join(data.keys())
values = ', '.join(['%s'] * len(data))

sql = 'INSERT INTO {table}({keys}) VALUES ({values}) ON DUPLICATE KEY UPDATE'.format(table=table, keys=keys, values=values)
update = ','.join([" {key} = %s".format(key=key) for key in data])
sql += update
try:
    if cursor.execute(sql, tuple(data.values())*2):
        print('Successful')
        db.commit()
except:
    print('Failed')
    db.rollback()
db.close()

ここで構築されたSQL文は、実際に文を挿入されていますが、ON DUPLICATE KEY UPDATEの増加の後ろに、これは主キーがすでに存在する場合、そのような場所として、アップデートを実行することを意味し、我々はまだ入ってくるデータid 20120001、しかし、年齢は20から21に変化するが、このデータに挿入されませんが、20120001のIDデータに更新されます。

ここでは、このように構築され、完全なSQLは次のようになります。

INSERT INTO students(id, name, age) VALUES (%s, %s, %s) ONDUPLICATE KEY UPDATE id = %s, name = %s, age = %s

データが更新されたこと、それがフィールドの内容の更新が続いているので、それは、重複キーUPDATE主キーのフィールドを、更新された部分よりも後に、上記と比較してSQL挿入操作が既に存在します。だから、ここでは6%sになります。したがって、実行の後ろに()2を乗じた第2のパラメータタプルの方法は、2つの要因になります。

このように、私たちは、その後、存在するデータを挿入しない主キーは、機能的なデータの存在が更新されて達成することができます。

6.データの削除

次のように操作が比較的簡単である、あなたはDELETEステートメントを使用することができます削除し、あなたがターゲット表名を指定して、削除したい条件を削除する必要があり、さらに有効にするデシベルのcommit()メソッドを使用する必要があり、その例は以下のとおりです。

table = 'students'
condition = 'age > 20'

sql = 'DELETE FROM  {table} WHERE {condition}'.format(table=table, condition=condition)
try:
    cursor.execute(sql)
    db.commit()
except:
    db.rollback()

db.close()

ここでは、条件を削除し、テーブルの名前を指定します。削除条件を変化させることができるので、オペレータ等は、コネクタ等のようなAND、ORと、等LIKE条件に等しい、より小さい、より大きい有するので、さらなる複雑な構造の決意条件ない、直接の条件文字列として削除を達成するために渡します。

7.クエリデータ

その後、クエリで非常に重要な操作を、残して、挿入、変更、または削除操作。

ここでは、クエリのSELECTステートメントを使用している、のは感じることの例を使用してみましょう:

sql = 'SELECT * FROM students WHERE age >= 20'

try:
    cursor.execute(sql)
    print('Count:', cursor.rowcount)
    one = cursor.fetchone()
    print('One:', one)
    results = cursor.fetchall()
    print('Results:', results)
    print('Results Type:', type(results))
    for row in results:
        print(row)
except:
    print('Error')

結果:

Count: 4
One: ('20120001', 'Bob', 25)
Results: (('20120011', 'Mary', 21), ('20120012', 'Mike', 20), ('20120013', 'James', 22))
Results Type: <class 'tuple'>
('20120011', 'Mary', 21)
('20120012', 'Mike', 20)
('20120013', 'James', 22)

ここでは、SQLステートメントを構築し、高齢者20歳以上の学生がチェックアウトした後、()メソッドは、もはやここでのdbの必要とされているコミットするために注意を払うことができます()メソッドを実行するために渡されました。その後、我々は、クエリ結果の数、ストリップ現在の例では、4つあり、得られた結果の数を取得するには、カーソルの行数プロパティを呼び出すことができます。

我々はfetchone()メソッドをコールし、このメソッドは、最初のデータの結果を得ることができ、その後、結果は、フィールドは最初の要素であるタプルの要素の順序に対応するタプル形態は、最初のフィールドのIDであります第二の要素は2番目のフィールド名です、と。その後、我々は、すべてのデータ結果を取得し、その結果とタイプをプリントアウトすることができます()メソッド、fetchAllのを呼び出して、それが各要素が記録され、二重のタプルです。私たちは一つ一つから、その出力、その出力を横断します。

しかし、それは代わりに、すべてのデータを得るための4つのデータ、fetall()メソッドを示し、ここで問題に気づきましたか?なぜわずか3?その内部実装は、クエリ結果へのオフセットポインタがあるためである、最初のデータの先頭にオフセットのポインタ、彼らが得るために長い時間がかかるだろうように、データポインタが次へとシフトされ、一度撮影しましたデータの次。だから我々が最初にfetchone()メソッド一度と呼ばれる、次のデータ、はfetchAll()メソッドに、このようなオフセットポインタポイントの結果は、すべてのデータの最後までオフセットデータを取得するようにはfetchAll()メソッドを指すポインタを返します結果は3つだけなので、ここでは、オフセットポインタの概念を理解することです。

データ量が大きいのであれば、我々は、すべてが一緒に出て、whileループプラスfetchone()すべてのデータを取得する方法ではなく、fetchAllの()を使用fetchAllの()することができ、すべてのタプル形式のリターンになり、その後、職業コストが非常に高くなります。一つ一つを取得するために、次の方法を使用することをお勧めします。

sql = 'SELECT * FROM students WHERE age >= 20'
try:
    cursor.execute(sql)
    print('Count:', cursor.rowcount)
    row = cursor.fetchone()
    while row:
        print('Row:', row)
        row = cursor.fetchone()
except:
    print('Error')
Python资源分享qun 784758214 ,内有安装包,PDF,学习视频,这里是Python学习者的聚集地,零基础,进阶,都欢迎

従って、各サイクルは、ポインタが簡単かつ効率的な検査で使用されるデータを、シフトします。

8.おわり

このセクションでは、MySQLデータベースを導入し、PyMySQLコンストラクタにいくつかのSQL文を操作し、我々は、後に実データ格納例でそれらを適用します。

おすすめ

転載: blog.51cto.com/14445003/2426849