ちゃぱ日記 / エンジニアリング / マネジメント

とあるプロダクトの運用組織のマネジメントしてる人の雑記

(Python)SQLite3のSelect結果の取得

SQLite3を使ってSELECT文を実行したあとのデータの取得方法にはいくつか種類があります。それらの取得結果の違いや、用途のイメージについて記載します。

 

取得方法

取得方法は4つあります。

  • fetcthone()
  • fetchall()
  • fetchmany()
  • イテレータとして利用(こちらの説明は割愛)

 

それぞれについて、取得結果等の説明を記載する。

 

fetchone()

Pythonのオフィシャルには以下の記載があります。

クエリ結果から次の row をフェッチして、1つのシーケンスを返します。これ以上データがない場合は None を返します。

どういう結果になるか実装を見てみます。

import sqlite3

import sqlite3
conn = sqlite3.connect('sample.db')

c = conn.cursor()

SQL = '''
SELECT *
  FROM TBL_PRODUCT
'''
c.execute(SQL)
print(c.fetchone())
print(c.fetchone())

複数商品がデータ登録されている前提です。結果は次のようになります。

(1, 'サンプル商品', 'サンプル用の商品です')
(2, 'グッド商品', '良い商品です')

取得できた全量から1件ずつ取り出します。

主キーで取ってくる場合などは、これで取ると楽ですね。

fetchall()

Pythonのオフィシャルには以下の記載があります。

全ての(残りの)クエリ結果の row をフェッチして、リストを返します。cursor の arraysize 属性がこの操作のパフォーマンスに影響することに気をつけてください。これ以上の row がない場合は、空のリストが返されます。

「残りの」というところがミソですね。どういう結果になるか実装を見てみます。

import sqlite3
conn = sqlite3.connect('sample.db')

c = conn.cursor()

SQL = '''
SELECT *
  FROM TBL_PRODUCT
'''
c.execute(SQL)
print(c.fetchall())

結果は次のようになります。

[(1, 'サンプル商品', 'サンプル用の商品です'),(2, 'グッド商品', '良い商品です')]

リストで全データが取られます。

では続いて「残りの」というところを確認してみます。最初にfetchone()でひとつ取り出しておいてからfetchall()します。

import sqlite3
conn = sqlite3.connect('sample.db')

c = conn.cursor()

SQL = '''
SELECT *
  FROM TBL_PRODUCT
'''
c.execute(SQL)
print(c.fetchone())
print(c.fetchall())

結果は次のようになります。確かに「残り」がリストで返ってきました。

(1, 'サンプル商品', 'サンプル用の商品です')
[(2, 'グッド商品', '良い商品です')]

fetchmany()

Pythonのオフィシャルには以下の記載があります。

クエリ結果から次の幾つかの row をフェッチして、リストを返します。これ以上データがない場合は空のリストを返します。

一回の呼び出しで返される row の数は、size 引数で指定できます。この引数が与えられない場合、cursor の arraysize 属性が利用されます。このメソッドは可能な限り指定された size の数の row を fetch しようとするべきです。もし、指定された数の row が利用可能でない場合、それより少ない数の row が返されます。

size 引数とパフォーマンスの関係についての注意です。パフォーマンスを最適化するためには、大抵、 arraysize 属性を利用するのがベストです。 size 引数を利用したのであれば、次の fetchmany() の呼び出しでも同じ数を利用するのがベストです。

取得するデータ量を決めて取得することができます。どういう結果になるか実装を見てみます。

import sqlite3
conn = sqlite3.connect('sample.db')

c = conn.cursor()

SQL = '''
SELECT *
  FROM TBL_PRODUCT
'''
c.execute(SQL)
print(c.fetchmany())
c.execute(SQL)
print(c.fetchmany(2))

意外だったのが「fetchmany()」と引数を指定しないときでした。最初の予想では「fetchall()」と同じ結果になると想像していたのですが異なりました。

(1, 'サンプル商品', 'サンプル用の商品です')
[(1, 'サンプル商品', 'サンプル用の商品です'),(2, 'グッド商品', '良い商品です')]

公式の説明を見ると「この引数が与えられない場合、cursor の arraysize 属性が利用されます」とあります。なるほど。見てみましょう。

c.execute(SQL)
print(c.arraysize)
c.arraysize = 99
print(c.arraysize)

こうすると、

1
99

となりました。

初期値は「1」なんですね。そして、上のように書き換えられるんですね。初めて知りました。

さいごに

あまり普段はSQLite3を使ってデータ加工しないので意識してませんでしたが、調べ始めると色々と知らないことが出てきました。

オフィシャルだけではどういった結果になるのかのイメージがわかなかったので、これがどなたかの参考になればと思います。

 

Pythonでリストを辞書に変換する

利用シーン

データをDBから取ってきたときに、Python内で利用しやすいように辞書として使いまわしたいなと思ったときに利用した。

実装の概略

テーブルからデータを取得。その結果を、辞書のキーをカラム名にして辞書として使う。

column_list = ["id", "product_name", "description"]
select_list = ["1","Good Box", "とても良い箱です"] # ここが実際にはSELECTした結果
new_dict = dict(zip(column_list, select_list))

例えば、SQLITEで一意にデータを取ってきた場合などは、

import sqlite3


conn = sqlite3.connect('sample.db')
c = conn.cursor()
sql = "select id, product_name, description  from tbl_product where id = 1"
c.execute(sql)

column_list = ["id", "product_name", "description"]
tbl_product = dict(zip(columns, c.fetchone()))

c.close()
conn.close()

のようにして辞書として使いまわせるようになる。

Google Spread SheetをPythonで利用していたらエラーとなった話

完全に自分用のメモです。

概要

PythonからGooglee Spread Sheetに対して書き込む処理を書いてました。そのときに発生したエラーと対処の仕方について記載します。自分の対処方針は本質的じゃない(回避)です。

発生したエラー

Pythonでgspreadを経由してGoogle Spread Sheetに書き込んでいたところ、ある程度書き込んだところで異常終了しました。 エラー内容は以下。

エラーコード:429
エラーメッセージ:Quota exceeded for quota metric 'Write requests' and limit 'Write requests per minute per user' of service 'sheets.googleapis.com' for consumer 'project_number:**********'."

まぁ、文字通りで1分間で書き込みし過ぎってことです。 Google APIのコンソールで、 「該当プロジェクトのダッシュボードに移動して画面下部にスクロール」→「Google Sheets APIをクリック」→「左メニューの割り当て選択」→「画面下部のWrite Requestsを選択 の順で選ぶと以下の画像のようにユーザー単位の1分の書き込みは100回に制限されていることがわかります。 f:id:as_chapa:20210110061813p:plain

対処方法

上限を上げる

Googleに申請すると上限値を上げることができるようです。以下のページでその方法が紹介されています。

www.cdatablog.jp

別のところにデータを書き込む

全然本質的ではないんですが、自分の場合、もっとデータを登録する可能性があったので、SQLiteでDB作ることにしました。そっちのほうが何の制限も気にしないで良いので。 (複数環境で開発しているので、DBファイルの保管をどうしようかなという別の悩みが発生するのですが・・・)

参考リンク

一連の開発をするにあたって参考にしてきた記事をメモしておきます。

gspread

gspread — gspread 3.6.0 documentation

gspreadライブラリの使い方まとめ!Pythonでスプレッドシートを操作する | たぬハック

Google API

Google Spread Sheets に Pythonを用いてアクセスしてみた - Qiita

上下ではなく役割だ(勝手にわたしのマネジメントスキル可視化プロジェクト)

過去分の記事はこちらにあります。

as-chapa.hatenablog.com

本題

シリーズ的に始めたものの、スキルというよりは、マインドセットのことを書きがちだなぁ。

 

自身のキャリアを振り返ると、割と早いタイミングでリーダーとしての役割を与えられたと思う。入社4年目のまだまだペーペーのときだった。

それから月日は経ち、転職をしたりしながら、今もそのようなポジションで仕事をしている。

 

リーダー、マネージャーという役割の人たちは、えてして、組織図の上のほうに位置する。リーダーやマネージャーにぶら下がる形でメンバーがいる。

そのせいか、ついつい「自分が上である」という錯覚を与えられる。

これについて自分が意識していることを書いてみようと思う。

 

意識していること

「リーダーやマネージャーはただの役割であって、立場が上なわけではない」ということを意識している。

前回にも似ているが、この辺の意識を忘れると、ついつい奢ってしまい、メンバーへのリスペクトの気持ちも薄れる気がしている。

あとは、こう考えることでリーダーやマネージャーをもう少し楽に捉えてできるのではないかとも思う。なんでもやらなきゃいけないわけではないし、できなきゃいけないわけでもない。色んなスキルを持ったメンバーをまとめて、組織に必要な成果に結びつける役割(他にも色々とやることはありますが)なだけなんだと。

 

自分はソフトウェアエンジニアたちのリーダー的な仕事をしているので、その例で書いてみる。

プログラムを書く役割の人はとても大事で、そもそもその人がいないとアウトプットがゼロになる。もちろん設計する役割も大切。

自分はそういった人たちをまとめている役割なだけなので、偉いからとか、仕事ができるからではない。プログラムを書くという仕事でいったら、メンバーのほうが自分なんかよりよっぽど上手だと思う。

 

さいごに

周囲の人も気を遣ってくれたりするし、組織図でも上に書かれるし、で、錯覚させられるシーンが多いので、「役割である」という意識を忘れないように心がけている。

相手をリスペクトする(勝手にわたしのマネジメントスキル可視化プロジェクト)

過去分の記事はこちらにあります。

as-chapa.hatenablog.com

本題

仕事だけに必要なものではないですが、「相手をリスペクトする」という心がけについて書いてみようと思います。

こういうことを書くと偉そうな感じになってしまいますが、明らかに自分よりも社会経験が豊富であるにも関わらずスキルが低く、向上心もない、という人が職場にはいたりします(今の職場では、そういえば見かけないような気もするけど)。 自分よりも社会経験が浅い人でもありえます。

そういうときにまず心がけるのが「相手をリスペクトする」ことです。 パッと見で「スキルも低いし、向上心もないなぁ・・・」と見えても、ミクロで見ていくと「絶対に」自分よりも優れているところがあります。絶対にあります(大事なので2回言う)。

「相手をリスペクトする」姿勢で見ていると、そういう点が見えてくると思います。そうするとおのずと「あぁ、あの人はこういう点がすごいなぁ」と素直に感じるようになり、結果、心がけのつもりだった「相手へのリスペクト」が心からのものに変わります。

なぜそんなことが必要なのか?

マネージャーをしているとチームのパフォーマンス」にフォーカスが当たります。 マネージャーが色眼鏡で見ていたり、変な格付けをしているようだと、チームにもそれが伝播します。その結果、対人関係のギスギスした状態が生まれます。この状態がチームのパフォーマンスにプラスに作用することはないと信じてます。

さいごに

ちょっと偉そうなことを書いたりもしましたが、とても大事なことだなぁと思います。これとセットで持つべきとして「謙虚さ」もあるのかなぁと思ってます。これについてもどこかで書けたら。

上に書いた「リスペクト」「謙虚さ」みたいな話は書籍「Team Geek」でも大切なものとして扱われています。とても良い本だったので、こちらも参考になると思います。

余談

上に書いた「スキルが低く、向上心もない」は、ドイツの軍人ハンマーシュタイン=エクヴォルトさん(ハンス・フォン・ゼークトの説もある)が定義した以下の分類の「愚鈍で怠慢」に当たるのかなぁと。ということは、自分の考えも加えるとリスペクトはしつつ、具体的な指示出しして指示を忠実に実行してもらえばいいということになるのか。

  • 利口で勤勉 - 参謀に適している。
  • 利口で怠慢 - 指揮官に適している。
  • 愚鈍で怠慢 - 命令を忠実に実行するのみの役職に適している。
  • 愚鈍で勤勉 - このような者を軍隊において重用してはならない。

(出典:Wikipedia

Pythonの実装について(CPython / PyPy / Stackless Python)

プログラミング言語Python」と一口に言っても、Python自体がどのように実装されているかには種類がある。別件を調べている中で、Pythonの実装に関する話題が出たので表面部分について少し整理する。

Pythonの実装の種類

ざっと書くだけでも以下の種類がある。(出展:Wikipedia

  • CPython:作者によってC言語で書かれたバージョン。通常「Python」といえばこのCPythonを指す。
  • Stackless Python:Cスタックを使わずに独自のスタック(Pythonスタック)で実装したもの。
  • Unladen Swallow:GoogleのチームによるPythonの実装
  • JythonJava仮想マシン上に移植したもの。PythonからJavaのライブラリを使うことができる。
  • IronPython.NET Framework/Monoで動作するPythonC#で実装されている。.NET Frameworkのライブラリを使うことができる。動的言語ランタイム上に構築されているため、既存の.NETアプリケーションへマクロ言語として搭載することも可能となっている。
  • PyPy:Python (RPython) によるPythonの実装
  • Psyco:CPython向けのJITコンパイラ
  • PyMite:組み込み向けの実装、AVRなどに対応。
  • tinypy:同じく組み込み向けの実装。ソースコードが 64 kB未満と非常に軽量なことが謳われている。
  • MicroPython:組み込み向けの実装。256 kB以上のフラッシュを推奨。
  • Pyodide:WebAssembly向けの実装

どれを調べるか?

低レイヤ向け、組み込み向けは、普段の業務や興味の中で出てこないので調査から除外。 2021年1月時点で「Jython」「IronPython」はPython2系のみの対応なので除外。 「Unladen Swallow」は、Google Codeを見ても2013年のIssueで止まっており、今となってはソースの閲覧もできなさそうなので除外(Wikipediaはこういうの除外しておいてほしい・・・)。

というわけで、生き残ったのは「CPython」「PyPy」「Stackless Python」。これらを軸に調べてみる(が、調べた結果をキレイにまとめるには至らなかった・・・)。

CPythonのデメリット?

「PyPy」は「速度」、「Stackless Python」は「スレッドベースのプログラミング」を推してくる。 これらがCPythonにおけるデメリットで、その解消のために生まれてきたものたちが上のふたつの実装ということになる。 ちなみに「PyPy」は「Stackless Python」に似たような機能も実装されているようだ。

doc.pypy.org

さいごに

全く細かいところに行きつかなかったが、おおよその違いはわかった。もともとASGIを調べていたところから「PyPy」の話に派生したのだけど、単純に「速度」だけだとしっくりきていなかった。「Stackless Python」と絡めて調べたことで「スレッドベース」のキーワードが出てきて、やっとASGIと繋がった。

参考リンク

pypy開発の基礎知識を入門者向けに解説!Pythonと比較した処理速度の速さとは?pypyのインストール方法も紹介 | A-STAR(エースター) ※この記事は基本を理解しやすかった

PyPyの基礎知識まとめ その1 - Qiita

Stackless Pythonでは、プログラムがユーザをファンクションコールする! - Qiita

同じ土俵に立つ(勝手にわたしのマネジメントスキル可視化プロジェクト)

勝手にわたしのマネジメントスキル可視化プロジェクト(えぇ、自分で勝手にやってるだけです)」の第一弾。

 

記念すべき第一回は「同じ土俵に立つ」

 

何か物ごとを調整していくときに、まず最初に自分が心がけていることです。

コミュニケーションをする上で絶対にやったほうがいいと思っています。

どういうこと?

平たく言うと、コミュニケーションする相手、ないしは集団と、「ベースの知識 / 情報量」を合わせること。

 

何かを調整しようとしたときに、悪意なくすれ違って会話が成り立たないことがよくあると感じています。それってなんでなんだろう?と考えていたときに、「ベースの知識 / 情報量」が揃ってないからだと思い至りました。

これを揃えた状態を「同じ土俵に立った状態」と自分の中で定義しています。

「同じ」土俵?

ここでポイントだと思っているのが、「相手の」土俵に立つでもなく、「自分の」土俵に立たせるでもなく、「同じ」土俵に立つという表現で理解しているところ。

例えば、エンジニアと顧客(ITに詳しくない)とのコミュニケーションの場合に、完全に相手の土俵に立つとITの会話ができない。かといって、自分の土俵に立たせるにはハードルが高い。

そういったときにある程度のITの補足をしながら、同じレベルで話せる状態=「同じ土俵に立った状態」を作る。

 

これを意識することで、双方にとってコミュニケーションのしやすさがグッと上がる。

 

集団においても同じ考えで進めると、チームビルディングの基礎ができると思います。

さいごに

社内でこの話をちょっとしたときに「なるほど」と言ってくれる人がいたので、文章としてまとめてみました。

基本的なことだと思いますが、だからこそずっと大事に思っていることでもあります。

もしこの記事を読んで「なるほど」と思って、コミュニケーションの取り方が変わるようなことがあると嬉しいです。