Python复习概览 第2部分。主要讨论数据存储
接下来是有关数据保存的回顾,延续之前的内容。
请参考以下其他回顾事项。
概括Python复习第1篇。包括基本语法等内容。
《Python简介-数据存储篇》
请访问以下链接:[ざっくりPythonのおさらい その2。おもにデータ保存]
https://qiita.com/48hands/items/ab86b7463268e669d216
【Python快速回顾 之三。Numpy和Pandas】
https://qiita.com/48hands/items/b1a71000533e129b27f2
使用Python处理RDB
事前准备好进行MySQL-Connector-Python、SQLAlchemy和PyMySQL的包安装。
pip install mysql-connector-python sqlalchemy pymysql
不使用 ORM 的实现示例
SQLite3 → SQLite三
import sqlite3
# コネクション生成 ファイルに永続化したい場合
conn = sqlite3.connect('my_sqlite.db')
# コネクション生成 メモリ上で完結させる場合はこっちを使う。
# conn = sqlite3.connect(':memory:')
# カーソルの生成
cursor = conn.cursor()
# テーブルの作成
sql = """
CREATE TABLE IF NOT EXISTS persons(
id INTEGER PRIMARY KEY AUTOINCREMENT
,name STRING
)
"""
cursor.execute(sql)
conn.commit()
# データのINSERT
cursor.execute("INSERT INTO persons(name) VALUES('Hanako')")
cursor.execute("INSERT INTO persons(name) VALUES('Taro')")
cursor.execute("INSERT INTO persons(name) VALUES('Yuichi')")
cursor.execute("INSERT INTO persons(name) VALUES('Makio')")
conn.commit()
# データのSELECT
sql = "SELECT * from persons"
cursor.execute(sql)
# カーソルに結果が入っているので受け取る
# fetchall()メソッドを使う。
result = cursor.fetchall()
for user_id, name in result:
print(user_id, name)
# コネクションのクローズ
conn.close()
MySQL是一种开源的关系型数据库管理系统。
几乎和SQLite一样。
import mysql.connector
# コネクションの設定
conn = mysql.connector.connect(host='127.0.0.1', port=3306, user='root',
# password='password',
# database='my_db'
)
# カーソルの生成
cursor = conn.cursor()
# データベース作成
cursor.execute('CREATE DATABASE IF NOT EXISTS my_db')
# テーブル作成
cursor.execute('CREATE TABLE IF NOT EXISTS my_db.persons('
'id int NOT NULL AUTO_INCREMENT,'
'name varchar(20) NOT NULL,'
'PRIMARY KEY(id)'
')')
# データのINSERT
for i in range(10):
cursor.execute(
'INSERT INTO my_db.persons(name) values("Robot-{}")'.format(str(i + 1)))
# コミット
conn.commit()
# データのSELECT
cursor.execute('SELECT * FROM my_db.persons')
for user_id, name in cursor.fetchall():
print(user_id, name)
# カーソルのクローズ
cursor.close()
# コネクションクローズ
conn.close()
使用SQLAlchemy进行编程实现
如果将数据库设置为SQLite内存,请按以下步骤操作:
创建”persons”表,并使其能够作为”Person”对象进行处理。
import sqlalchemy
import sqlalchemy.ext.declarative
import sqlalchemy.orm
# sqliteを使ってメモリで完結させる。
# echoをTrueにすると、実際に発行したSQLを確認できる
engine = sqlalchemy.create_engine('sqlite:///:memory:', echo=True)
# おまじない
Base = sqlalchemy.ext.declarative.declarative_base()
# Personモデルの定義
class Person(Base):
__tablename__ = 'persons'
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True,
autoincrement=True)
name = sqlalchemy.Column(sqlalchemy.String(20))
# これを実行するとメモリ上にpersonsテーブルが作成される。
Base.metadata.create_all(engine)
# セッションの作成
Session = sqlalchemy.orm.sessionmaker(bind=engine)
session = Session()
# データの登録
person_list = [Person(name='Hanako'), Person(name='Taro'), Person(name='Makio')]
for p in person_list:
# addメソッドを使って登録する
session.add(p)
session.commit()
# データを取得してnameを変更してupdateする。
p1 = session.query(Person).filter_by(name='Taro').first()
p1.name = 'Mike'
session.add(p1)
session.commit()
# データを削除する
p1 = session.query(Person).filter_by(name='Hanako').first()
session.delete(p1)
session.commit()
# 一覧を取得する
persons = session.query(Person).all()
for person in persons:
print(person.id, person.name)
如果要将数据库持久化到SQLite文件中,只需将引擎设置为以下方式。
engine = sqlalchemy.create_engine('sqlite:///dev_db_sqlalchemy', echo=True)
如果希望将数据库设置为MySQL,可以按照以下方式进行配置。
# mysql+pymysqlを指定する
url = 'mysql+pymysql://username:password@127.0.0.1/my_db'
engine = sqlalchemy.create_engine(url, echo=True)
使用Python处理DBM
DBM是Python的标准库,可以在需要简便地使用缓存保存等情况下使用。
import dbm
with dbm.open('cache', 'c') as db:
# 文字列をキャッシュとして保存する
db['key1'] = 'value1'
db['key2'] = 'value2'
# NOTE: 数値はそのまま保存するとエラーになる。文字列のみ対応している。
# db['key3'] = 123
with dbm.open('cache', 'r') as db:
print(db.get('key1')) # b'value1'となり、バイナリ型になって表示される
print(db.get('key2').decode('utf-8')) # utf-8でデコードするとvalue2として表示される
b'value1'
value2
使用Python处理Memcached
Memcached是一种软件,它可以将数据存储在内存中,然后在访问数据库之前检索数据,以减少对数据库的访问次数。
【Memcached】
http://memcached.org/
【内存缓存】
http://memcached.org/
安装Memcached
# Linuxの場合
wget https://www.memcached.org/files/memcached-1.5.10.tar.gz
tar -zxvf memcached-1.5.10.tar.gz
cd memcached-1.5.10
./configure && make && make test && sudo make install
# Macの場合はbrew installでできる。
brew install memcached
brew services start memcached
# python-memchacheパッケージをインストールしておく
pip install python-memcached
以下是用于处理Python的代码。
import memcache
# memcacheのクライアント設定
db = memcache.Client(['127.0.0.1:11211'])
# キーバリューの形式でセットする。
db.set('key1', 'value1')
db.set('key2', 'value2')
# データの取得
print(db.get('key1'))
可以设置保持时间。
将值设置在time中,如下所示。
import time
import memcache
# memcacheのクライアント設定
db = memcache.Client(['127.0.0.1:11211'])
# キーバリューの形式でセットする。
db.set('key1', 'value1', time=1)
# データの取得
print(db.get('key1'))
# sleepする
time.sleep(2)
# データ取得できないことを確認する。
# 値が取れない場合はNoneが返却される
print(db.get('key1'))
运行后,会变成以下的样子。
value1
None
同时使用 RDB 和 Memcache
作为准备工作,将数据存入SQLite中。
import sqlite3
cursor.execute('CREATE TABLE IF NOT EXISTS persons'
'(id INTEGER PRIMARY KEY AUTOINCREMENT, name STRING)')
cursor.execute('INSERT INTO persons(name) VALUES("Makio")')
conn.commit()
conn.close()
如果在这个状态下无法从Memcache中获取值,则进行数据库访问。
import sqlite3
import memcache
# memcacheのクライアント設定
mem = memcache.Client(['127.0.0.1:11211'])
# SQLiteのコネクション、カーソル設定
conn = sqlite3.connect('test_sqlite_memcached.db')
cursor = conn.cursor()
def get_person_id(name):
"""
nameからidを返却するメソッド
"""
# Memcachedからidがとれればそのまま返却
# DBにアクセスしない。
person_id = mem.get(name)
if person_id:
return person_id
# 以下はMemchachedにデータがない場合
# DBに対して検索処理
sql= 'SELECT * FROM persons WHERE name = "{}"'.format(name)
cursor.execute(sql)
person = cursor.fetchone()
if not person:
raise Exception('No person data')
person_id, name = person # アンパッキング
# 60秒以内だったらMemchacheから値を参照できるように
# Memchachedに値を設定しておく。
mem.set(name, person_id, time=60)
return person_id
print(get_person_id("Makio"))
使用泡菜进行对象的存储
将Python数据直接保存的库
import pickle
class Person(object):
def __init__(self, name):
self.name = name
obj = {
'key1': [1,2,3,4,5],
'key2': ['dev', 'prod', 'test'],
'key3': Person('Makio')
}
# データの保存処理。
# バイナリ形式でオブジェクトを保存する。
with open('obj.pickle', 'wb') as f:
pickle.dump(obj, f)
# pickleファイルからデータを読み込む。
with open('obj.pickle', 'rb') as f:
read_obj = pickle.load(f)
# 読込できたか確認する。
print(read_obj)
print(read_obj['key1'])
print(read_obj['key2'])
print(read_obj['key3'].name)
执行结果。
{'key1': [1, 2, 3, 4, 5], 'key2': ['dev', 'prod', 'test'], 'key3': <__main__.Person object at 0x10e328588>}
[1, 2, 3, 4, 5]
['dev', 'prod', 'test']
Makio