2553810 ランダム
 ホーム | 日記 | プロフィール 【フォローする】 【ログイン】

傀儡師の館.Python

PR

日記/記事の投稿

カレンダー

キーワードサーチ

▼キーワード検索

カテゴリ

バックナンバー

2020年03月
2020年02月
2020年01月
2019年12月
2019年11月
2019年10月
2019年09月
2019年08月
2019年07月
2019年06月

フリーページ

プロフィール


kugutsushi

サイド自由欄

設定されていません。
2014年01月01日
XML
カテゴリ:Python
querycsv.py を使うと、次のように SQLデータベースと同じ形式でクエリが実行できる。-i でデータファイルを指定する。

querycsv.py -i testdata.csv "select somecolumn from testdata;"


地味に便利かもしれない。ということで、いじってみた。

querycsv.py -i testdata.csv "select max(somecolumn) from testdata;"


みたいなこともできる。sum(somecolumn)とかもできる。どこまで対応しているか? SQLite にできることはできる。なぜならば、sqlite3.connect(":memory:") で開いた SQLite にデータを CSVファイルから読み込んでから、それに対してクエリを実行しているから。なんだそういうことかぁ。-f オプションを指定するとオンメモリではなく、SQLite ファイルを使う。ちなみに、insert とか update とかしても元の CSV ファイルには影響がない。

オンメモリでなく SQLite のデータベースファイルに書き出すこともできる。-f オプションで SQLite のデータベースファイルを指定し、適当なクエリを書く。-k オプションをつけるのを忘れないように。keep の意味で、実行後に SQLite ファイルを残すということ。-k がないと、SQLite ファイルが残らない。

querycsv.py -i testdata.csv -f testdata.sqlite -k "select * from testdata;"


生成された SQLite 形式のデータベースを入力として使うこともできる。同じデータに対して操作をするなら、その方が早いしね。-u で use するファイルを指定。

querycsv.py -u testdata.sqlite "select distinct somecolumn from testdata;"


実行する SQL文はファイルにしておいて、-s オプションで指定することもできる。複数のデータベースファイルを JOIN するとかできる。

問題としては、このままだと日本語のデータが入っているとエラーになる。

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)


まあ、そうだろうなとちょこちょこと手を入れたら、日本語も扱えるようになった。便利かもしれない。

どのあたりに手を入れたかと言えば、前に紹介した unicodecsv を使ってcsv データの読み書きをする。読み込んだ文字列はユニコードになるから、ascii の文字列とユニコードの文字列を + で連結しようとするとエラーになるので、そのあたり手を入れてみた。表示のときの文字幅が日本語だとちょっとやっかいなので、次のような関数を作って文字幅とした。全角文字か不明の場合は、2文字分の幅、それ以外なら 1 文字分の幅とする。u'あア a' なら 6 が返る。でも、端末で表示すると、そういう単純なやり方だときれいにそろわなかったりするけど...。経験的にスペース量を調整するようなコードを書いてみたが、スペースを入れない方が、むしろ見やすくて、潔い態度かもしれないなぁとか呟きながらも、ゴニョゴニョ...。

# 文字幅のカウント

import unicodedata

def uwidth(ustr):
l = 0
for uc in ustr:
l += 2 if unicodedata.east_asian_width(uc) in ('F','W','A') else 1
return l


あと、querycsv.py のソースを見ていて、csv.Sniffer という存在に今更ながら気づいた。クォートがついているついてないとか、デリミターはなんだとか、形式を推定してくれるのね。って、前にも思ったことがある...。すぐ忘れる。

csvfile = open("example.csv", "rb")
dialect = csv.Sniffer().sniff(csvfile.read(1024))
csvfile.seek(0)
reader = csv.reader(csvfile, dialect)
...
参照 13.1. csv — CSV File Reading and Writing

querycsv だと、open するとき "rt" になっているけれど、"rb" の方がよさそうか。unicodecsv では、sniffer がないので、判定は csv.Sniffer を使って、読み込むところだけやらせた。

とか、久々にコードをいじくっているうちに、大晦日があけて元旦を迎えてしまった。そういえば、まだ、私 Python 2 使ってんのねw

とりあえず、こんな風になった。備考の後ろの「|」が揃ってるのね。単純に全角だから2文字分とかカウントしているだけではだめ。ljust でスペースを入れているところも直さないといけなかった。



ということで、なんだか中途半端でいい加減な終わり方だけど、本年もよろしくお願いいたします。



無料アクセス解析






最終更新日  2014年01月01日 08時58分41秒
コメント(0) | コメントを書く
[Python] カテゴリの最新記事



Copyright (c) 1997-2020 Rakuten, Inc. All Rights Reserved.