Soumettre la recherche
Mettre en ligne
PlaySQLAlchemyORM2017.key
•
3 j'aime
•
1,856 vues
泰 増田
Suivre
神戸Pythonの会 #14 の講演資料です。
Lire moins
Lire la suite
Ingénierie
Signaler
Partager
Signaler
Partager
1 sur 43
Télécharger maintenant
Télécharger pour lire hors ligne
Recommandé
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
泰 増田
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?
Yoshitaka Kawashima
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
Yahoo!デベロッパーネットワーク
OAuth 2.0のResource Serverの作り方
OAuth 2.0のResource Serverの作り方
Hitachi, Ltd. OSS Solution Center.
データ収集の基本と「JapanTaxi」アプリにおける実践例
データ収集の基本と「JapanTaxi」アプリにおける実践例
Tetsutaro Watanabe
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
Shohei Koyama
Recommandé
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
泰 増田
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?
Yoshitaka Kawashima
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
Kentaro Matsui
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
Yahoo!デベロッパーネットワーク
OAuth 2.0のResource Serverの作り方
OAuth 2.0のResource Serverの作り方
Hitachi, Ltd. OSS Solution Center.
データ収集の基本と「JapanTaxi」アプリにおける実践例
データ収集の基本と「JapanTaxi」アプリにおける実践例
Tetsutaro Watanabe
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada
インフラエンジニアの綺麗で優しい手順書の書き方
インフラエンジニアの綺麗で優しい手順書の書き方
Shohei Koyama
エンジニアから飛んでくるマサカリを受け止める心得
エンジニアから飛んでくるマサカリを受け止める心得
Reimi Kuramochi Chiba
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
Hiroshi Tokumaru
クソコード動画「Managerクラス」解説
クソコード動画「Managerクラス」解説
MinoDriven
テストコードの DRY と DAMP
テストコードの DRY と DAMP
Yusuke Kagata
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Chihiro Ito
Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。
Kenjiro Kubota
Mavenの真実とウソ
Mavenの真実とウソ
Yoshitaka Kawashima
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Hiro H.
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
Ryuji Tsutsui
[db tech showcase Tokyo 2017] E21: InfluxDB+αで時系列データの異常検知を可視化してみた by 株式会社インサイ...
[db tech showcase Tokyo 2017] E21: InfluxDB+αで時系列データの異常検知を可視化してみた by 株式会社インサイ...
Insight Technology, Inc.
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
Shuyo Nakatani
負荷テストを行う際に知っておきたいこと 初心者編
負荷テストを行う際に知っておきたいこと 初心者編
まべ☆てっく運営
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
Shota Shinogi
エンジニアも知っておきたいAI倫理のはなし
エンジニアも知っておきたいAI倫理のはなし
Yasunori Nihei
例外設計における大罪
例外設計における大罪
Takuto Wada
DSPでgolangの屍を超えた話 (オレシカナイト Vol.2)
DSPでgolangの屍を超えた話 (オレシカナイト Vol.2)
Yuki Katada
先端技術とメディア表現1 #FTMA15
先端技術とメディア表現1 #FTMA15
Yoichi Ochiai
グラフ構造のデータモデルをPower BIで可視化してみた
グラフ構造のデータモデルをPower BIで可視化してみた
CData Software Japan
最近のやられアプリを試してみた
最近のやられアプリを試してみた
zaki4649
OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理
Tadashi Miyazato
An Overview of Designing Microservices Based Applications on AWS - March 2017...
An Overview of Designing Microservices Based Applications on AWS - March 2017...
Amazon Web Services
SQLAlchemy Primer
SQLAlchemy Primer
泰 増田
Contenu connexe
Tendances
エンジニアから飛んでくるマサカリを受け止める心得
エンジニアから飛んでくるマサカリを受け止める心得
Reimi Kuramochi Chiba
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
Hiroshi Tokumaru
クソコード動画「Managerクラス」解説
クソコード動画「Managerクラス」解説
MinoDriven
テストコードの DRY と DAMP
テストコードの DRY と DAMP
Yusuke Kagata
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Chihiro Ito
Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。
Kenjiro Kubota
Mavenの真実とウソ
Mavenの真実とウソ
Yoshitaka Kawashima
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Hiro H.
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
Ryuji Tsutsui
[db tech showcase Tokyo 2017] E21: InfluxDB+αで時系列データの異常検知を可視化してみた by 株式会社インサイ...
[db tech showcase Tokyo 2017] E21: InfluxDB+αで時系列データの異常検知を可視化してみた by 株式会社インサイ...
Insight Technology, Inc.
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
Shuyo Nakatani
負荷テストを行う際に知っておきたいこと 初心者編
負荷テストを行う際に知っておきたいこと 初心者編
まべ☆てっく運営
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
Shota Shinogi
エンジニアも知っておきたいAI倫理のはなし
エンジニアも知っておきたいAI倫理のはなし
Yasunori Nihei
例外設計における大罪
例外設計における大罪
Takuto Wada
DSPでgolangの屍を超えた話 (オレシカナイト Vol.2)
DSPでgolangの屍を超えた話 (オレシカナイト Vol.2)
Yuki Katada
先端技術とメディア表現1 #FTMA15
先端技術とメディア表現1 #FTMA15
Yoichi Ochiai
グラフ構造のデータモデルをPower BIで可視化してみた
グラフ構造のデータモデルをPower BIで可視化してみた
CData Software Japan
最近のやられアプリを試してみた
最近のやられアプリを試してみた
zaki4649
OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理
Tadashi Miyazato
Tendances
(20)
エンジニアから飛んでくるマサカリを受け止める心得
エンジニアから飛んでくるマサカリを受け止める心得
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
クソコード動画「Managerクラス」解説
クソコード動画「Managerクラス」解説
テストコードの DRY と DAMP
テストコードの DRY と DAMP
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Akkaとは。アクターモデル とは。
Akkaとは。アクターモデル とは。
Mavenの真実とウソ
Mavenの真実とウソ
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
[db tech showcase Tokyo 2017] E21: InfluxDB+αで時系列データの異常検知を可視化してみた by 株式会社インサイ...
[db tech showcase Tokyo 2017] E21: InfluxDB+αで時系列データの異常検知を可視化してみた by 株式会社インサイ...
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
負荷テストを行う際に知っておきたいこと 初心者編
負荷テストを行う際に知っておきたいこと 初心者編
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
エンジニアも知っておきたいAI倫理のはなし
エンジニアも知っておきたいAI倫理のはなし
例外設計における大罪
例外設計における大罪
DSPでgolangの屍を超えた話 (オレシカナイト Vol.2)
DSPでgolangの屍を超えた話 (オレシカナイト Vol.2)
先端技術とメディア表現1 #FTMA15
先端技術とメディア表現1 #FTMA15
グラフ構造のデータモデルをPower BIで可視化してみた
グラフ構造のデータモデルをPower BIで可視化してみた
最近のやられアプリを試してみた
最近のやられアプリを試してみた
OSSを利用したプロジェクト管理
OSSを利用したプロジェクト管理
En vedette
An Overview of Designing Microservices Based Applications on AWS - March 2017...
An Overview of Designing Microservices Based Applications on AWS - March 2017...
Amazon Web Services
SQLAlchemy Primer
SQLAlchemy Primer
泰 増田
Automating Management of Amazon EC2 Instances with Auto Scaling - March 2017 ...
Automating Management of Amazon EC2 Instances with Auto Scaling - March 2017 ...
Amazon Web Services
ITB2017 - Slaying the ORM dragons with cborm
ITB2017 - Slaying the ORM dragons with cborm
Ortus Solutions, Corp
Database programming
Database programming
Shree M.L.Kakadiya MCA mahila college, Amreli
ColdBox Hierarchical MVC - Transform Your Monolith
ColdBox Hierarchical MVC - Transform Your Monolith
Ortus Solutions, Corp
En vedette
(6)
An Overview of Designing Microservices Based Applications on AWS - March 2017...
An Overview of Designing Microservices Based Applications on AWS - March 2017...
SQLAlchemy Primer
SQLAlchemy Primer
Automating Management of Amazon EC2 Instances with Auto Scaling - March 2017 ...
Automating Management of Amazon EC2 Instances with Auto Scaling - March 2017 ...
ITB2017 - Slaying the ORM dragons with cborm
ITB2017 - Slaying the ORM dragons with cborm
Database programming
Database programming
ColdBox Hierarchical MVC - Transform Your Monolith
ColdBox Hierarchical MVC - Transform Your Monolith
Similaire à PlaySQLAlchemyORM2017.key
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
Hideki Takase
OpenStack, Hadoop -- OSSクラウドの最新動向
OpenStack, Hadoop -- OSSクラウドの最新動向
Masanori Itoh
Rclex: ElixirでROS!!
Rclex: ElixirでROS!!
Hideki Takase
OpenJDK コミュニティに参加してみよう #jjug
OpenJDK コミュニティに参加してみよう #jjug
Yuji Kubota
受託開発とRubyGems
受託開発とRubyGems
Koichi ITO
PySpark Intro Part.2 with SQL Graph
PySpark Intro Part.2 with SQL Graph
Oshitari_kochi
Skinny Framework 進捗どうですか? #fud_scala
Skinny Framework 進捗どうですか? #fud_scala
Kazuhiro Sera
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
Hideki Takase
ウェブアーキテクチャの歴史と未来
ウェブアーキテクチャの歴史と未来
Kazuho Oku
uroboroSQLの紹介 (OSC2017 Nagoya) #oscnagoya
uroboroSQLの紹介 (OSC2017 Nagoya) #oscnagoya
Kenichi Hoshi
Osc2012.dbに行ってきました
Osc2012.dbに行ってきました
Masaru Kobashigawa
OpenStack Summit Vancouver YVR Ops
OpenStack Summit Vancouver YVR Ops
NTT Communications Technology Development
Keycloakの実際・翻訳プロジェクト紹介
Keycloakの実際・翻訳プロジェクト紹介
Hiroyuki Wada
Oracleがnode.jsをやり始めたというのだが!
Oracleがnode.jsをやり始めたというのだが!
Hiroshi Hayakawa
Scalaでのプログラム開発
Scalaでのプログラム開発
Kota Mizushima
JavaOne 2015 JDK Update (Jigsaw) #j1jp
JavaOne 2015 JDK Update (Jigsaw) #j1jp
Yuji Kubota
LINE BOOT AWARDS に挑む ~テクノロジーファーストでもいいじゃない
LINE BOOT AWARDS に挑む ~テクノロジーファーストでもいいじゃない
Kazumi IWANAGA
Splunkと各種ツールによるAWSの管理
Splunkと各種ツールによるAWSの管理
kinunori
ISUCON夏期講習2015_2 実践編
ISUCON夏期講習2015_2 実践編
SATOSHI TAGOMORI
minneで学ぶクラウド脳
minneで学ぶクラウド脳
Uchio Kondo
Similaire à PlaySQLAlchemyORM2017.key
(20)
関数型言語ElixirのIoTシステム開発への展開
関数型言語ElixirのIoTシステム開発への展開
OpenStack, Hadoop -- OSSクラウドの最新動向
OpenStack, Hadoop -- OSSクラウドの最新動向
Rclex: ElixirでROS!!
Rclex: ElixirでROS!!
OpenJDK コミュニティに参加してみよう #jjug
OpenJDK コミュニティに参加してみよう #jjug
受託開発とRubyGems
受託開発とRubyGems
PySpark Intro Part.2 with SQL Graph
PySpark Intro Part.2 with SQL Graph
Skinny Framework 進捗どうですか? #fud_scala
Skinny Framework 進捗どうですか? #fud_scala
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ロボットシステムのつくりかた 〜Robot Operating Systemというアプローチ〜
ウェブアーキテクチャの歴史と未来
ウェブアーキテクチャの歴史と未来
uroboroSQLの紹介 (OSC2017 Nagoya) #oscnagoya
uroboroSQLの紹介 (OSC2017 Nagoya) #oscnagoya
Osc2012.dbに行ってきました
Osc2012.dbに行ってきました
OpenStack Summit Vancouver YVR Ops
OpenStack Summit Vancouver YVR Ops
Keycloakの実際・翻訳プロジェクト紹介
Keycloakの実際・翻訳プロジェクト紹介
Oracleがnode.jsをやり始めたというのだが!
Oracleがnode.jsをやり始めたというのだが!
Scalaでのプログラム開発
Scalaでのプログラム開発
JavaOne 2015 JDK Update (Jigsaw) #j1jp
JavaOne 2015 JDK Update (Jigsaw) #j1jp
LINE BOOT AWARDS に挑む ~テクノロジーファーストでもいいじゃない
LINE BOOT AWARDS に挑む ~テクノロジーファーストでもいいじゃない
Splunkと各種ツールによるAWSの管理
Splunkと各種ツールによるAWSの管理
ISUCON夏期講習2015_2 実践編
ISUCON夏期講習2015_2 実践編
minneで学ぶクラウド脳
minneで学ぶクラウド脳
Plus de 泰 増田
Taming robotframework
Taming robotframework
泰 増田
Open bio2004 biopython
Open bio2004 biopython
泰 増田
Python languageupdate (2004)
Python languageupdate (2004)
泰 増田
Robot Framework (のSelenium2Libraryのお話)
Robot Framework (のSelenium2Libraryのお話)
泰 増田
Django boodoo
Django boodoo
泰 増田
wxPython入門(大阪Pythonユーザの集まり2014/03)
wxPython入門(大阪Pythonユーザの集まり2014/03)
泰 増田
Plus de 泰 増田
(6)
Taming robotframework
Taming robotframework
Open bio2004 biopython
Open bio2004 biopython
Python languageupdate (2004)
Python languageupdate (2004)
Robot Framework (のSelenium2Libraryのお話)
Robot Framework (のSelenium2Libraryのお話)
Django boodoo
Django boodoo
wxPython入門(大阪Pythonユーザの集まり2014/03)
wxPython入門(大阪Pythonユーザの集まり2014/03)
PlaySQLAlchemyORM2017.key
1.
SQLAlchemy 入門 ORM編 for Kobe
Python Meetup #14 2017/10/20 Kobe Japan
2.
Yasushi Masuda PhD (
@whosaysni ) Tech team, Core IT grp. IT Dept. MonotaRO Co., LTD. Pythonista since 2001 (2.0~) • elaphe (barcode library) • oikami.py (老神.py) • PyCon JP founder 翻訳もろもろ
3.
参考文献 オンラインドキュメント: http://docs.sqlalchemy.org/en/rel_1_1/ (古いけど)和訳: http://omake.accense.com/static/doc-ja/ sqlalchemy/
4.
準備 sakila DB SQLite版 https://github.com/jOOQ/jOOQ/jOOQ-examples/Sakila/sqlite-sakila-db/ Sakila •
MySQL エンジニア 作のサンプルDB • レンタルビデオ屋 (...通じます?) のモ デル • BSD ライセンス スキーマのドキュメントは下記 https://dev.mysql.com/doc/sakila/en/sakila-structure-tables.html (上記のサイトのSQLiteデータベースバイナリは壊れているので、以下から取得してください) https://github.com/wallymathieu/sakila-sample-database-ports/blob/master/sqlite-sakila-db/sqlite-sakila.sq
5.
アジェンダ 前回のあらすじ automapでORMを体験しよう おまけ:そのほかのマッピング方法
6.
前回のあらすじ SQLAlchemyを3行で エンジンを使ってみましょう SQL式を使ってみましょう ORMを使ってみましょう
7.
# クエリはエンジンで実行する engine = create_engine(engine_url) engine.execute('select ... from ...') # SQLを表すクエリオブジェクトを構築できる film = table('film', column('film_id'), ...) q = select([film]).where(film.c.film_id==1) engine.execute(q) # スキーマ定義を使うとDDLも生成・実行できる film = Table('Film', MetaData(), Column('film_id', INTEGER), ...) f.create(bind=engine) engine.execute(select([film.c.film_id, ...])).fetchone() # 宣言的ORMはクラスでテーブル構造を表現する Base = declarative_base() class Film(Base): film_id = Column(INTEGER, primary_key=True) ... # ORMでのレコードの操作にはセッションを使う Session = sessionmaker(bind=engine) session = Session() session.query(Film).get(1) f = session.query(Film).filter(Film.film_id>3).first() f.rating = 'PG-18' # カラム値の変更 session.flush() # 保存
8.
ORM
9.
ORMでできたら嬉しいこと再確認 • DBレコードをオブジェクトのように扱いたい • 1レコード1オブジェクト •
別テーブルのレコード参照→別クラスのオブジェクトの参照 • オブジェクトのデータをDBにシリアライズしたい • インスタンスを保存・あとで取り出したい • DBの機能を使ってオブジェクトを操作したい • オブジェクトの検索・フィルタリング
10.
SQLAlchemyのORM • 1つのテーブルを1つのクラスにマッピングする • テーブルのレコードがクラスのインスタンス •
別テーブルのレコード(のオブジェクト)は、マッピングクラスにリレー ション (relation) を定義して参照できる • セッションを使ってオブジェクトデータをDBから読み出し・保存できる • セッションのフラッシュ(精算)で、オブジェクトとDBの状態とが一致する • セッションのコミット(承認)で、変更内容がDBに永続化される • オブジェクトを取り出すときに SQL式 で検索条件を設定できる
11.
ORM操作の流れ マッピングを設定する セッションクラスを設定する セッションインスタンスを作る オブジェクトを DBから取り出す オブジェクトを クラスから生成する セッションに 追加する オブジェクトを 更新する セッションをflush/rollback マッピング 関連の操作 セッションの 操作 セッションを破棄 毎回セッションを 作る時のサイクル セッションを 使い続けるときの サイクル
12.
classic(古典的) mapping 古いやつ昔からあるやつ 新しいやつを支えている 古の魔法 =
よくわからんから避けられる declarative(宣言的) mapping 新しいやつ 書きやすい 流行の宣言的API 古の魔法x現代の魔法=よくわからないけど便利 SAでORMといえばだいたいこっちの話 automapping 宣言的マッピングをある程度自動化してくれる ある意味最強の呪文 SQLAlchemyのマッピング
13.
古典的マッピング Tableオブジェクト Column foo Column bar Column
baz ... エンティティクラス マッピングクラス 仕掛けの付いた foo 仕掛けの付いた bar 仕掛けの付いた baz ... method qux method quux method qux method quux ... その他有象無象 ... その他有象無象 mapperの仕掛けた 内部オブジェクト mapper
14.
宣言ベースクラス マッピングクラスの 定義 宣言的マッピング Column foo Column bar Column
baz ... マッピングクラス 仕掛けの付いた foo 仕掛けの付いた bar 仕掛けの付いた baz ... method qux method quux method qux method quux ... その他有象無象 ... その他有象無象 内部オブジェクト Tableオブジェクト 宣言ベースクラスの機能 Column foo Column bar Column baz mapping
15.
自動マッピング ベースクラス マッピングクラスの 定義 自動マッピング マッピングクラス 仕掛けの付いた foo 仕掛けの付いた bar 仕掛けの付いた
baz ... method qux method quux method qux method quux ... その他有象無象 ... その他有象無象 得体の知れない 内部オブジェクト Tableオブジェクト ベースクラス機能 Column foo Column bar Column baz (スキーマ定義) DB上のスキーマ構造 mapping
16.
セッション • セッション:トランザクションのようなもの エンジンのDB接続一つが対応している 通常、セッションの持続中は、他のプログラムは セッションが捕まえている接続にアクセスできない • オブジェクトの読み出し:SELECT 新たなオブジェクトをセッションに追加:INSERT オブジェクトのアトリビュートを更新:UPDATE セッションにオブジェクトをdeleteさせる:DELETE •
必要に応じてクエリを実行し、DB(のトランザクション)と 状態を同期する • 通常は、セッションをcommit()するとDBを更新する (トランザクションをCOMMITする)
17.
セッション Program query A SELECT
A record Aobject A start tracking A ... (updates) flag A as "dirty" reflect new/dirty changes flush() start tracking B ... add(b) UPDATE A INSERT B COMMIT BEGIN (create) Database (new object) commit()
18.
使ってみましょう • automapを使って楽してマッピングを設定しましょう (declarativeやclassic mappingは後で) •
セッションを作成して、マッピングを使ってみましょう
19.
ORM操作の流れ マッピングを設定する セッションクラスを設定する セッションインスタンスを作る オブジェクトを DBから取り出す オブジェクトを クラスから生成する セッションに 追加する オブジェクトを 更新する セッションをflush/commit/rollback マッピング 関連の操作 セッションの 操作 セッションを破棄 毎回セッションを 作る時のサイクル セッションを 使い続けるときの サイクル
20.
マッピングベースクラスを作る ↓ エンジンを指定してマッピングを準備する (DBからスキーマを呼び出してマッピングする) automappingの流れ
21.
# SQLエコーバックモードを有効にして接続する >>> from sqlalchemy import create_engine >>> e = create_engine('sqlite:///sqlite-sakila.sq', echo=True) # filmテーブルがあるか確かめる >>> e.execute('select count(*) from film').scalar() 2017-10-01 07:27:45,014 INFO sqlalchemy.engine.base.Engine select count(*) from film 2017-10-01 07:27:45,014 INFO sqlalchemy.engine.base.Engine () 1002 >>> automappingを使ってみましょう (エンジンの生成) ↑SQLAlchemyのエコーバック
22.
# 自動マッピングベースクラスを生成 >>> from sqlalchemy.ext.automap import automap_base >>> Base = automap_base() # エンジンを指定してテーブル情報を反映させる >>> Base.prepare(engine=e, reflect=True) 2017-10-01 07:37:18,014 INFO sqlalchemy.engine.base.Engine SELECT CAST .... ... 2017-10-01 07:37:18,019 INFO sqlalchemy.engine.base.Engine SELECT name FROM sqlite_master WHERE type='table' ORDER BY name 2017-10-01 07:37:18,019 INFO sqlalchemy.engine.base.Engine () 2017-10-01 07:37:18,021 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("actor") 2017-10-01 07:37:18,022 INFO sqlalchemy.engine.base.Engine () 2017-10-01 07:37:18,023 INFO sqlalchemy.engine.base.Engine SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE name = 'actor' AND type = 'table' 2017-10-01 07:37:18,023 INFO sqlalchemy.engine.base.Engine () 2017-10-01 07:37:18,024 INFO sqlalchemy.engine.base.Engine PRAGMA foreign_key_list("actor") 2017-10-01 07:37:18,024 INFO sqlalchemy.engine.base.Engine () 2017-10-01 07:37:18,024 INFO sqlalchemy.engine.base.Engine SELECT sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE name = 'actor' AND type = 'table' 2017-10-01 07:37:18,024 INFO sqlalchemy.engine.base.Engine () 2017-10-01 07:37:18,026 INFO sqlalchemy.engine.base.Engine PRAGMA index_list("actor") 2017-10-01 07:37:18,026 INFO sqlalchemy.engine.base.Engine () ... >>> list(Base.classes) # テーブルが読み込めている [<class 'sqlalchemy.ext.automap.category'>, <class 'sqlalchemy.ext.automap.city'>, <class 'sqlalchemy.ext.automap.store'>, <class 'sqlalchemy.ext.automap.film_text'>, <class 'sqlalchemy.ext.automap.language'>, <class 'sqlalchemy.ext.automap.country'>, <class 'sqlalchemy.ext.automap.actor'>, <class 'sqlalchemy.ext.automap.film_category'>, <class 'sqlalchemy.ext.automap.customer'>, <class 'sqlalchemy.ext.automap.film_actor'>, <class 'sqlalchemy.ext.automap.inventory'>, <class 'sqlalchemy.ext.automap.address'>, <class 'sqlalchemy.ext.automap.staff'>, <class 'sqlalchemy.ext.automap.rental'>, <class 'sqlalchemy.ext.automap.payment'>, <class 'sqlalchemy.ext.automap.film'>, <class 'sqlalchemy.ext.automap.location'>] >>> automappingを使ってみましょう (ベースクラスの準備) ↓テーブル一覧を取得 テーブルの情報を取得
23.
# Base.classes は(自動的に作られた)テーブル名でアクセスできる >>> Film = Base.classes.film >>> Film <class 'sqlalchemy.ext.automap.film'> # Filmクラスはマッピング済み >>> dir(Film) ['__abstract__', '__class__', ... , 'description', 'film_id', 'language', 'language_id', 'last_update', 'length', 'metadata', 'original_language_id', 'prepare', 'rating', 'release_year', 'rental_duration', 'rental_rate', 'replacement_cost', 'special_features', 'title'] # スキーマ定義もできている >>> Film.__table__ Table('film', MetaData(bind=None), Column('film_id', INTEGER(), table=<film>, primary_key=True, ...), Column('title', VARCHAR(length=255), table=<film>, nullable=False), ...) >>> automappingを使ってみましょう (マッピングクラスを参照する)
24.
ORM操作の流れ マッピングを設定する セッションクラスを設定する セッションインスタンスを作る オブジェクトを DBから取り出す オブジェクトを クラスから生成する セッションに 追加する オブジェクトを 更新する セッションをflush/commit/rollback マッピング 関連の操作 セッションの 操作 セッションを破棄 毎回セッションを 作る時のサイクル セッションを 使い続けるときの サイクル
25.
セッションを作ってみましょう (セッションの生成) # セッションを作るクラスを sessionmaker で作る # 使うエンジンが一定ならこのとき指定する >>> from sqlalchemy.orm import sessionmaker >>> Session = sessionmaker(bind=e) >>> session = Session() >>> session <sqlalchemy.orm.session.Session object at ...> # dir(session) してみましょう
26.
ORM操作の流れ マッピングを設定する セッションクラスを設定する セッションインスタンスを作る オブジェクトを DBから取り出す オブジェクトを クラスから生成する セッションに 追加する オブジェクトを 更新する セッションをflush/commit/rollback マッピング 関連の操作 セッションの 操作 セッションを破棄 毎回セッションを 作る時のサイクル セッションを 使い続けるときの サイクル
27.
DBからオブジェクトを取り出しましょう (クエリを生成する) # session.query() は Model クラスを問い合わせるための # クエリオブジェクトを返す >>> Film = Base.classes.film >>> q = session.query(Film) >>> q <sqlalchemy.orm.query.Query object at ...> # str(q) するとクエリを返す(実行はされない) >>> str(q) 'SELECT film.film_id AS film_film_id, ... FROM film'
28.
DBからオブジェクトを取り出しましょう (クエリを実行する) # 実際にオブジェクトを取り出す操作を実行したときに # クエリが実行される >>> q.get(1) # プライマリキーが 1 2017-10-01 23:29:52,678 INFO sqlalchemy.engine.base.Engine SELECT film.film_id AS film_film_id, ... FROM film WHERE film.film_id = ? ... <sqlalchemy.ext.automap.film object at 0x1013b2810> >>> q.first() # 条件に一致する最初のレコード 2017-10-01 23:29:52,678 INFO sqlalchemy.engine.base.Engine SELECT ... FROM film LIMIT ? OFFSET ? 2017-10-19 23:29:52,678 INFO sqlalchemy.engine.base.Engine (1, 0) <sqlalchemy.ext.automap.film object at 0x1013bce10> >>> q[3] # インデクスでアクセスしても取り出せる ... <sqlalchemy.ext.automap.film object at 0x1013d0250> セッションの中では 同じレコードは 同じオブジェクト
29.
DBからオブジェクトを取り出しましょう (クエリを実行する) # all() は条件に一致する全てのレコードを返す >>> q.all() ... [<sqlalchemy.ext.automap.film object at 0x1013d00d0>, <sqlalchemy.ext.automap.film object at 0x1013bcf90>, ...] # クエリをスライスすると "LIMIT ... OFFSET ..." >>> q[:10] 2017-10-01 23:36:51,815 INFO sqlalchemy.engine.base.Engine SELECT ... FROM film LIMIT ? OFFSET ? ... [<sqlalchemy.ext.automap.film object at 0x1013d00d0>, ...]
30.
DBからオブジェクトを取り出しましょう (クエリ条件を指定する) # filter() に SQL 式を渡せば絞りこめる # filter() は条件の付加されたクエリオブジェクトを返す >>> q2 = q.filter(Film.language_id==1) >>> q2 <sqlalchemy.orm.query.Query object at 0x1013d9690> >>> str(q2) 'SELECT film.film_id ... FROM film WHERE film.language_id = ?' # 一致条件は filter_by でも指定できる >>> q.filter_by(language_id=2).all() 2017-10-01 23:52:27,650 INFO sqlalchemy.engine.base.Engine SELECT ... FROM film WHERE film.language_id = ? # filter, filter_by をつなげて条件を積み上げられる >>> q.filter(Film.rating=='G').filter(Film.title.like('%MOON%')).all() 2017-10-02 00:05:34,056 INFO sqlalchemy.engine.base.Engine SELECT ... FROM film WHERE film.rating = ? AND film.title LIKE ? .... [<sqlalchemy.ext.automap.film object at ...>, ...]
31.
オブジェクトの値にアクセスしましょう (オブジェクトの中身) >>> f = q.first # オブジェクトにはテーブルのカラムと同じ名前のアトリビュート がある # language_id だけでなく lanugage というアトリビュートがある # _collection のついた怪しげなアトリビュートもある >>> dir(f) [..., 'description', 'film_actor_collection', 'film_category_collection', 'film_id', 'inventory_collection', 'language', 'language_id', 'last_update', 'length', 'metadata', 'original_language_id', 'prepare', 'rating', 'release_year', 'rental_duration', 'rental_rate', 'replacement_cost', 'special_features', 'title']
32.
オブジェクトの値にアクセスしましょう (カラム値にアクセスする) # カラム名のアトリビュートから値にアクセスできる >>> f.title 'ACADEMY DINOSAUR' # カラムのデータ型に応じて適切なPythonデータ型になる >>> [f.title, f.length, f.rental_rate, f.last_update] ['ACADEMY DINOSAUR', 86, Decimal('0.99'), datetime.datetime(2011, 9, 14, 18, 5, 32)]
33.
inventory_collection オブジェクトの値にアクセスしましょう (外部キー参照にアクセスする) # language は自動マッピングで作られた Language への参照 # 参照すると自動的にクエリを実行する >>> f.language.name 2017-10-02 00:22:06,996 INFO sqlalchemy.engine.base.Engine SELECT language.language_id ... FROM language WHERE language.language_id = ? ... 'English' # *_collection は他のテーブルからの参照の逆参照で、リストを返す >>> f.inventory_collection 2017-10-02 00:11:48,828 INFO sqlalchemy.engine.base.Engine SELECT inventory.inventory_id ... FROM inventory WHERE ? = inventory.film_id ... [<sqlalchemy.ext.automap.inventory object at 0x101510850>, ...] film language film film inventory inventory backref
34.
ORM操作の流れ マッピングを設定する セッションクラスを設定する セッションインスタンスを作る オブジェクトを DBから取り出す オブジェクトを クラスから生成する セッションに 追加する オブジェクトを 更新する セッションをflush/rollback マッピング 関連の操作 セッションの 操作 セッションを破棄 毎回セッションを 作る時のサイクル セッションを 使い続けるときの サイクル
35.
オブジェクトの値を更新しましょう (アトリビュートの更新) # アトリビュートに代入すると、値をセットできる # まだ SQL は実行されない >>> f.title = 'HOLY GRAIL' >>> f.title 'HOLY GRAIL' # 次のDB操作前にUPDATEが実行される(トランザクション内) >>> q.count() 2017-10-02 00:48:07,739 INFO sqlalchemy.engine.base.Engine UPDATE film SET title=? WHERE film.film_id = ? # セッションを rollback() すると更新はすべて破棄される # ロールバックしたオブジェクトを再度参照するとDBクエリが実行される >>> s.rollback() >>> f.title 2017-10-02 00:51:24,693 INFO sqlalchemy.engine.base.Engine SELECT film.film_id ... 'ACADEMY DINOSAUR' # セッションを flush() すると(トランザクション内で)更新SQLが走る >>> f.title = 'HOLY GRAIL' >>> s.flush() 2017-10-02 06:20:56,690 INFO sqlalchemy.engine.base.Engine UPDATE film SET title=? WHERE film.film_id = ? ... # セッションを commit() するとトランザクションを COMMIT する >>> s.commit() 2017-10-02 06:29:34,104 INFO sqlalchemy.engine.base.Engine COMMIT
36.
オブジェクトの値を更新しましょう (リレーションの更新) # リレーションのアトリビュートに代入すると、値をセットできる # 代入するのはマッピングクラスのインスタンス >>> Language = Base.classes.language >>> lang = session.query(Language).get(2) >>> lang.id, lang.name (2, 'Italian') >>> f.language_id, f.language.language_id, f.name (1, 1, 'English') >>> f.lanugage = lang # 注意: language_id は変更されない! # flush() してはじめて外部キーが更新される >>> f.language_id, f.language.language_id, f.name (1, 2, 'Italian') >>> session.flush() >>> f.language_id, f.language.language_id, f.name (2, 2, 'Italian') #### 大事なこと:リレーションを更新したら必ず flush() する
37.
ORM操作の流れ マッピングを設定する セッションクラスを設定する セッションインスタンスを作る オブジェクトを DBから取り出す オブジェクトを クラスから生成する セッションに 追加する オブジェクトを 更新する セッションをflush/rollback マッピング 関連の操作 セッションの 操作 セッションを破棄 毎回セッションを 作る時のサイクル セッションを 使い続けるときの サイクル
38.
オブジェクトを新規追加しましょう # カラムの値をキーワードパラメタで渡してオブジェクトを生成する >>> Language(language_id=99, name='Japanese', last_update=datetime.now()) <sqlalchemy.ext.automap.language object at 0x103243f60> >>> l = Language(language_id=99, name='Japanese', last_update=datetime.now()) # セッションに追加すると新規追加対象になる >>> s.add(l) # セッションを flush() すると INSERT 文が実行される >>> s.flush() 2017-10-02 07:12:26,651 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 2017-10-02 07:12:26,652 INFO sqlalchemy.engine.base.Engine INSERT INTO language (language_id, name, last_update) VALUES (?, ?, ?) 2017-10-02 07:12:26,652 INFO sqlalchemy.engine.base.Engine (99, 'Japanese', '2017-10-02 07:12:12.932744') >>>
39.
オブジェクトを削除しましょう # セッションの delete() メソッドに削除したいレコード(のオブジェクト)を渡す >>> s.delete(l) >>> s.flush() 2017-10-02 07:19:53,458 INFO sqlalchemy.engine.base.Engine SELECT ... FROM film WHERE ? = film.original_language_id 2017-10-02 07:19:53,464 INFO sqlalchemy.engine.base.Engine DELETE FROM language WHERE language.language_id = ? 2017-10-02 07:19:53,464 INFO sqlalchemy.engine.base.Engine (99,)
40.
まとめ • automapを使ってマッピングをDBから生成できる • session.query()
でクエリを生成して DBからオブジェクトを取り出す • 新しくオブジェクトを追加するときはセッションにadd() 削除するときは delete() • flush()するか、次にDBと同期する必要が出るまでクエリは実行 されない • セッションを commit() すると、トランザクションが反映される
41.
# ベースクラスを生成する from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() # ベースクラスを拡張するとORMで扱えるモデルクラスになる from sqlalchemy import Column, Integer, String, DateTime class Actor(Base): __tablename__ = 'actor' actor_id = Column(Integer,primary_key=True) first_name = Column(String) last_name = Column(String) last_update = Column(DateTime) def full_name(self): return '{} {}'.format( self.first_name, self.last_name) 宣言的マッピング
42.
# テーブルのスキーマ定義を作成する >>> from sqlalchemy import Table, Column, MetaData, Integer >>> foo_table = Table( ... 'foo', MetaData(), Column('bar', Integer)) # エンティティクラスを作成する >>> class Foo(object): ... def bar_is_odd(self): ... return bool(bar % 2) # マップする >>> from sqlalchemy.orm import mapper >>> mapper(Foo, foo_table) <Mapper at 0x105e332d0; Foo> # dir(Foo) してみましょう。 Foo.bar があることを確認しましょう。 # マッピングに失敗して、やりなおしたら以下のようなメッセージが出る場合: sqlalchemy.exc.ArgumentError: Class '...' already has a primary mapper defined. Use non_primary=True to create a non primary Mapper. clear_mappers() will remove *all* current mappers from all classes. >>> from sqlalchemy.orm import clear_mappers >>> clear_mappers() 古典的マッピング
43.
以上です。 おつかれさまでした!
Télécharger maintenant