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
广告
将在 10 秒后关闭
bannerAds