naritoブログ

【お知らせ】
新ブログができました。今後そちらで更新し、このサイトは更新されません(ウェブサイト自体は残しておきます)
このブログの内容に関してコメントしたい場合は、新ブログのフリースペースに書き込んでください

このブログの内容を新ブログに移行中です。このブログで見つからない記事は、新ブログにありま

Pythonで、SQLAlchemyを使う

約1290日前 2016年5月10日12:47
プログラミング関連
SQLAlchemy Python
SQLAlchemyをちょっと触ってみます。

インストール

pip install sqlalchemy


まず最初です。
models.pyとして保存しておきます。

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker


Base = declarative_base()


class User(Base):
__tablename__ = 'users'

id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)

if __name__ == "__main__":
engine = create_engine('sqlite:///db.sqlite3', echo=True)
Base.metadata.create_all(engine) # テーブル作成



テーブルの定義です。

class User(Base):
__tablename__ = 'users'

id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)



デー タベースへの接続には、 create_engine()を使います。
echo=Trueで、ログが表示されます。具体的にはSQL文が見れます。
'sqlite:///:memory:'と指定すると、メモリ内にdbを作るようです。なので、終わったら消えますね。
'sqlite:///db.sqlite3'は、カレントディレクトリのdb.sqlite3を作成しています。

engine = create_engine('sqlite:///db.sqlite3', echo=True)



テーブルを作成しています。
実際、これを実行したらdb.sqlite3がそこにはいました。

# テーブル作成
Base.metadata.create_all(engine) # テーブル作成


以下が実行結果です。

2016-05-10 03:02:25,218 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
2016-05-10 03:02:25,218 INFO sqlalchemy.engine.base.Engine ()
2016-05-10 03:02:25,219 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
2016-05-10 03:02:25,219 INFO sqlalchemy.engine.base.Engine ()
2016-05-10 03:02:25,220 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("users")
2016-05-10 03:02:25,221 INFO sqlalchemy.engine.base.Engine ()
2016-05-10 03:02:25,223 INFO sqlalchemy.engine.base.Engine
CREATE TABLE users (
id INTEGER NOT NULL,
name VARCHAR,
fullname VARCHAR,
password VARCHAR,
PRIMARY KEY (id)
)


2016-05-10 03:02:25,223 INFO sqlalchemy.engine.base.Engine ()
2016-05-10 03:02:25,281 INFO sqlalchemy.engine.base.Engine COMMIT



次は早速、何かデータを追加してみましょう。
add.pyとして保存します。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import User

engine = create_engine('sqlite:///db.sqlite3', echo=True)
Session = sessionmaker(bind=engine)
session = Session()

ed_user = User(name='ed', fullname='Ed Jones', password='edspassword')
session.add(ed_user)

session.add_all([
User(name='wendy', fullname='Wendy Williams', password='foobar'),
User(name='mary', fullname='Mary Contrary', password='xxg527'),
User(name='fred', fullname='Fred Flinstone', password='blah')])

session.commit()


接続とセッションの作成です。

engine = create_engine('sqlite:///db.sqlite3', echo=True)
Session = sessionmaker(bind=engine)
session = Session()


ユーザーを一件足してます。

ed_user = User(name='ed', fullname='Ed Jones', password='edspassword')
session.add(ed_user)


こちらは複数登録ですね。

session.add_all([
User(name='wendy', fullname='Wendy Williams', password='foobar'),
User(name='mary', fullname='Mary Contrary', password='xxg527'),
User(name='fred', fullname='Fred Flinstone', password='blah')])


これを忘れないようにします。
commit() は、現在処理されずに残っているデータの変更を全てデータベースに 反映して、トランザクションをコミットします。

session.commit()


実行結果です。

2016-05-10 03:20:30,955 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
2016-05-10 03:20:30,955 INFO sqlalchemy.engine.base.Engine ()
2016-05-10 03:20:30,957 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
2016-05-10 03:20:30,957 INFO sqlalchemy.engine.base.Engine ()
2016-05-10 03:20:30,959 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2016-05-10 03:20:30,964 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
2016-05-10 03:20:30,965 INFO sqlalchemy.engine.base.Engine ('ed', 'Ed Jones', 'edspassword')
2016-05-10 03:20:30,968 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
2016-05-10 03:20:30,968 INFO sqlalchemy.engine.base.Engine ('wendy', 'Wendy Williams', 'foobar')
2016-05-10 03:20:30,969 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
2016-05-10 03:20:30,969 INFO sqlalchemy.engine.base.Engine ('mary', 'Mary Contrary', 'xxg527')
2016-05-10 03:20:30,969 INFO sqlalchemy.engine.base.Engine INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
2016-05-10 03:20:30,969 INFO sqlalchemy.engine.base.Engine ('fred', 'Fred Flinstone', 'blah')
2016-05-10 03:20:30,970 INFO sqlalchemy.engine.base.Engine COMMIT



次は検索です。
query.pyを以下のようにしてみます。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import User

engine = create_engine('sqlite:///db.sqlite3', echo=False)
Session = sessionmaker(bind=engine)
session = Session()

for row in session.query(User).all():
print(row.id, row.name, row.fullname, row.password)


実行結果
今回はechoをFalseにしてみました。

1 ed Ed Jones edspassword
2 wendy Wendy Williams foobar
3 mary Mary Contrary xxg527
4 fred Fred Flinstone blah


更新です。update.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import User

engine = create_engine('sqlite:///db.sqlite3', echo=False)
Session = sessionmaker(bind=engine)
session = Session()

# 更新処理
row = session.query(User).filter_by(id=1).one()
row.name = "torina"
session.add(row)
session.commit()




最後は削除です。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import User

engine = create_engine('sqlite:///db.sqlite3', echo=False)
Session = sessionmaker(bind=engine)
session = Session()

# 削除処理
row = session.query(User).filter_by(id=1).one()
session.delete(row)
session.commit()


全て削除する場合は、以下のようにします。

session.query(User).delete()
session.commit()



公式
http://www.sqlalchemy.org/

1.0チュートリアル
http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html

日本語チュートリアル
http://omake.accense.com/static/doc-ja/sqlalchemy/ormtutorial.html

Tips
http://qiita.com/zakuro9715/items/7e393ef1c80da8811027