DBD::SQLite::db do failed: unable to open database file at の対応

DBD::SQLite::db do failed: unable to open database file at の対応

macのapacheでsqlite3を使おうとした時、DBD::SQLite::db do failed: unable to open database file at のエラーが発生した。
検索はできているので、ファイルは見つかっているよう。
INSERTやUPDATEでエラーが発生している。

原因

sqlite3のデータベースは更新時にジャーナルファイルを作成する。
そのジャーナルファイルが作成できない場合に発生する。

対策

sqlite3のデータベースファイルの保存フォルダにアクセス権限を設定する。

1
chmod 777 db_dir
同じタグの記事
同じカテゴリの記事

jythonのヒープメモリ設定

jythonのヒープメモリ設定

jythonプログラムがOutOfMemoryErrorで落ちてしまったとき、その原因はヒープメモリが不足していることが原因だと考えられる。
もっとも、それほどメモリを使ってしまうプログラムが問題かもしれないが、今時のPCならpythonにギガ単位のメモリを使わせても、プログラム自体が簡略化できるのであれば、それもありだと思う。

ヒープメモリ設定方法

現在の割当容量を確認する

1
2
3
jython --print
C:> C:\usr\java\bin\java -Xmx512m -Xss1024k -classpath C:\usr\jython\jython.jar; -Dpython.home=C:\usr\
jython -Dpython.executable=C:\usr\jython\bin\jython.exe -Dpython.launcher.uname=windows -Dpython.launcher.tty=true org.python.util.jython

-Xmx512mより、ヒープサイズが512MBであることが確認できる。

-Xmxを1024MBに拡張

Windows

1
SET JAVA_MEM=-Xmx1024m

Linux Bash

1
export JAVA_MEM=-Xmx1024m

改めて割当容量を確認する

1
2
3
jython --print
C:> C:\usr\java\bin\java -Xmx1024m -Xss1024k -classpath C:\usr\jython\jython.jar; -Dpython.home=C:\usr\
jython -Dpython.executable=C:\usr\jython\bin\jython.exe -Dpython.launcher.uname=windows -Dpython.launcher.tty=true org.python.util.jython
同じタグの記事
同じカテゴリの記事

pythonのバージョン選び

pyhtonのバージョン選び

本当なら、迷わずpython3を選ぶべきなんだろうけど、
置かれている仕事の状況では、python3がベストとならない事があった。
なので、未だにpython2を使うことがよくある。

python2を使う場面

javaで実装されたpythonことjythonを使う場合。

他システムのデータを取り出すときjavaのAPIを呼び出すため、jythonを利用している。
しかし、jythonはpythonのバージョンが2.7.0なので、python2としてコーディングする必要がある。

余談だが、jythonでのコーディングでpythonのバージョン以外で気になることろは

  • sqlite3モジュールがない。(sqlite.jarを使ってJDBC接続すればsqlite3に接続できる)
  • JavaのStringクラスとpythonの文字列の自動変換あたりで思わぬ動作をすることがある。(文字列の結合で失敗することがある。StringBuilderなどを用いて結合すれば問題ない)

サーバーのpythonのバージョンが2.6

利用しているredhatサーバのpythonのバージョンが2.6。サーバのモジュールのバージョン更新はなかなかできないので、2.6のまま利用している。

余談だが、python2.6でコーディングしていて気になるてん

  • ”.format()でフォーマットの中括弧の中の番号を省略できない。(‘{},{}’.format(a,b)が利用できない。ちゃんと'{0},{1}’.format(a,b)という風に、数字を指定する必要がある)

共有端末のmacのpythonがバージョン2.7

動作確認用macで動作するpythonのバージョンが2.7。動作確認用端末なので設定を変更することができない。

python2で問題があるか

python2でも、特に問題はない。
コンパイルエラーは標準ライブラリのパッケージ名が異なることくらい。
実行時エラーは、文字列関連でラフに処理しているところは、strとunicodeの違いでエラーになることがある。

サラッと書いた、このstrとunicodeの違いは、気にするのが面倒なところなので、ここを考えなくて良いだけでもpython3を使うメリットは十分にあると思う。

同じタグの記事
同じカテゴリの記事

Windowsでpython3 ZIPでダウンロードした場合

Windowsでpython3。ZIPでダウンロードした場合

なんらかの事情がって、pythonをインストーラーでなく、ZIPファイルをダウンロードして使う場合、準備が必要。

ZIPを解凍したディレクトリのpython36._pthのファイル名を変更

ZIPを解凍したディレクトリに保存されているpython36._pthのファイル名を変更する。
python36._pth → python36.pth

これを実行しないと、インタラクティブシェルを利用したときに、quit()が利用できない。
pythonの教本には普通に書いてあることができないので、いきなり躓いてしまう。

quit()が利用できないとき

ファイル名変更前にインタラクティブシェルに入ってしまった場合、quit()を利用できない。
そんなときはsysをimportしてexit(0)すればよい。

1
2
import sys
sys.exit(0)
同じタグの記事
同じカテゴリの記事

pythonでマルチスレッドプログラミング

pythonでマルチスレッドプログラミング

pythonは簡単にマルチスレッドで動作するプログラムを簡単に作れる。
javaだと、それ用にクラスを作成する必要があるが、pythonでは関数をマルチスレッドで動かすことができる。
ちょっと作ってみたツールが、性能的に問題がある場合、該当処理を関数に切り出し、それをマルチスレッドで動かせる。

とりあえずプログラムの全貌

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env python

import threading
import queue
import logging

def worker(q):
    '''pythonでキューを多重処理するスレッド'''
    while True:
        item = q.get()
        if item is None:
            break
        logging.info(item)

'''どのスレッドで処理されているかどうか見たいので、logging機能を使ってログ出力する'''
logging.basicConfig(
    format = '%(asctime)s [%(levelname)-5s] [%(thread)5d] (%(name)s) %(message)s',
    level = 'INFO')
'''開始メッセージを出力'''
logging.info('start')
'''処理キューを登録するためのqueueを作成する'''
q = queue.Queue()
'''キューを処理するスレッドを準備する'''
threads = []
for i in range(20):
    t = threading.Thread(target = worker, args = (q, ))
    t.start()
    threads.append(t)
'''キューにタスクを登録する'''
for item in range(100):
    q.put(item)
'''スレッドの数だけ、キュー終端のNoneをキューに登録する'''
for t in threads:
    q.put(None)
'''スレッドが終了することを待ち合わせる'''
for t in threads:
    t.join()
'''終了メッセージを出力'''
logging.info('end')

処理をする関数を作成する

1
2
3
4
5
6
7
def worker(q):
    '''pythonでキューを多重処理するスレッド'''
    while True:
        item = q.get()
        if item is None:
            break
        logging.info(item)

while Trueの無限ループを作成しておき、queueからキューを1つポップする。
キューからポップした値がNoneのときはループを抜ける。
キューの最後にNoneを入れるのは、後のキュー登録の後処理で行う。

検証用にloggingを準備する

1
2
 [%(thread)5d] (%(name)s) %(message)s',
    level = '
INFO')

loggingを利用するとログにスレッドのIDを出力できるようになる。
これを利用して、マルチスレッドで処理されていることを確認する。

空のキューを用意し、マルチスレッドで動作させるスレッドを用意する

1
2
3
4
5
6
7
q = queue.Queue()
'''キューを処理するスレッドを準備する'''
threads = []
for i in range(20):
    t = threading.Thread(target = worker, args = (q, ))
    t.start()
    threads.append(t)

先に空のキューを作成しておく。
そのキューを引数に取る、マルチスレッドで実行するスレッドを作成する。
実行したスレッドは、後で処理の待ち合わせをするために、リストに保存しておく。

キューにタスクを登録する

1
2
for item in range(100):
    q.put(item)

このサンプルではシンプルな数値を設定しているが、キューにはなんでも登録できるので、
DBから取得したデータや、DTOなど、なんでも自由に設定できる。

キューの終端を登録する

1
2
for t in threads:
    q.put(None)

マルチスレッドで実行される関数は、キューからNoneを取得した時点でスレッドを終了するように定義している。
なので、キューに実行すべきキューを登録した後に、スレッドの数だけ終端の合図(None)を設定しておく。

各スレッドが終了することを確認する

1
2
for t in threads:
    t.join()

スレッドのjoin()は、スレッドが完了したときに戻ってくる。
これを利用して、すべてのスレッドのjoin()が完了するまで処理を待つ。

まとめ

これらの応用することで、簡単にマルチスレッドで処理することができる。
私の場合は、処理は他のシステムのAPIを呼ぶことが多い。
他のシステムAPIがネックで、待ちが多く発生しているときなどは、その部分をマルチスレッドにし、
幾つか多重でリクエストをかけている。
同じデータを複数処理してももったいないので、キューに一度に一気に溜め込んでいる。
また、結果出力はsqliteを使うことが多いが、sqlite3はマルチに書き込むと思わぬエラーが発生することがあるので、
sqliteへの書き込みもスレッド化(シングル)し、各マルチ処理は書き込みキューへキューイングすることで実装している。

javaで作ればいくつもクラスを作って冗長になりがちな実装が、pythonだと1ファイルで簡単に作成できてしまう。

同じタグの記事
同じカテゴリの記事

atom 1.9

atom 1.9

pythonの実装にはatomを使っている

会社で使う都合上、プラグインを入れずにZIPファイルを解凍してatomを使っている。
(プログラムをインストールするには色々手続きが必要なため)

atomは1.8から、gitのcommitがatom上で実行できるのが便利。
また、pythonのインデントの自動解釈や、HTMLを作るときの自動補完などが便利。
そんなatomが…

ここから下の記事は古くなっている。下記の内容は、atom 1.9.1で解消されている。

8/9 atom 1.9 release

8月9日にatom1.9がリリースされた。早速ZIPファイルをダウンロードして解凍。
使ってみたところ…

IMEとの相性が悪い

IMEを確定するまでatomのエディタに反映されない。
これは気持ち悪い。
いつもは旧版など、最新版で上書きしてしまうのに、今回は1.8を退避していた。
1.8に戻してしまいました。
そのうち、IMEとの相性が良くなったら、改めて1.9にしたいと思います。

ちなみに、Windows32bit版、Windows64bit版、macOS版いずれでもダメです。

同じタグの記事
  • ありません。
同じカテゴリの記事

perlで日付を扱うならTime::Piece

perlで日付を扱うなら、Time::Pieceがお勧め。
time()とlocaltime()を使って処理するよりも、簡単に日付を加工できる。

現在を得る

1
2
use Time::Piece;
my $t = localtime;

日付をフォーマットする

1
print $t->strftime('%Y/%m/%d %H:%M:%S');

日付の要素を個別に取得する

1
2
print $t->year;
print $t->mon;

月末日を取得する

print $t->month_last_day;

日付の足し算

1
2
use Time::Seconds;
$t + ONE_DAY * 5 # 5日間足しこむ

文字列の日付をTime::Pieceに変換する

1
2
my $d = Time::Piece->strptime('20170803', 'Y%%m%d');
my $t = Time::Piece->strptime('2017/08/03 15:30:20', '%Y/%m/%d %H:%M:%S');

どの処理も、localtime関数で行うと、だらだらと記述しなくてはならないところが一発でできてしまう。
お勧めします。

同じタグの記事
同じカテゴリの記事

バッチ処理の基本・ファイル入出力

バッチ処理の基本といえば、ファイル入出力。
最近は、DBアクセスが基本となっているが、システム間連携などは、未だにファイル連携が多い。
連携されてきたファイルを直接取り込んでも良いけど、あまりにも格好悪いファイルは、事前にある程度整えておきたい。
そんな時に、バッチ処理が役立つ。
私がよく使い言語は、下記の4つ。それぞれの言語で、1つのファイルを読んで、1つのファイルを出力する雛形を置いておく。

1.pythonの場合(最近は、pythonでチョチョっと加工することが多いかも)

1
2
3
4
5
6
import codecs
with codecs.open('in.txt', 'r', 'utf_8') as r, codecs.open('out.txt', 'w', 'utf_8') as w:
    counter = 0
    for line in r:
        counter += 1
        w.write('{:03d}:{}'.format(counter, line))

とても簡潔に、描きたいロジックだけを書くことができます。

2.javaの場合(Javaで作らないと実行の承認が通らない時はJavaで作ります)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.lang.String;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.BufferedReader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardOpenOption;

public class FileIo {
    public static void main(String[] args) {
        try (
            BufferedReader r = Files.newBufferedReader(
                    Paths.get("in.txt"), StandardCharsets.UTF_8);
            Writer w = Files.newBufferedWriter(
                    Paths.get("out.txt"), StandardCharsets.UTF_8,
                    StandardOpenOption.WRITE,
                    StandardOpenOption.APPEND,
                    StandardOpenOption.CREATE)
        ) {
            String line = null;
            int counter = 0;
            while((line = r.readLine()) != null) {
                counter++;
                w.write(String.format("%03d:%s\n", counter, line));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

昔に比べれば、だいぶシンプルに書けるようにはなったけど、冗長な感じがする。
しかし、実行速度は結構速い。Java7以降は性能をほとんど気にせずコーディングしても、それなりのスピードで動いてくれる。

3.C#の場合(実行環境がWindowsの場合はC#で作ればだいたい動く)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Text;
using System.IO;

public class FileIo
{
    public static void Main()
    {
        try
        {
            using(StreamReader r = new StreamReader("in.txt", Encoding.GetEncoding("UTF-8")))
            using(StreamWriter w = new StreamWriter("out.txt", false, Encoding.GetEncoding("UTF-8")))
            {
                int counter = 0;
                while(r.Peek() >= 0)
                {
                    counter++;
                    w.WriteLine(string.Format("{0:000}:{1}", counter, r.ReadLine()));
                }
            }
        }
        catch (Exception e)
        {
            Console.Write(e.StackTrace);
        }
    }
}

Visual Studioがなくても、気合いでC#を簡単なテキストエディタでコーディングして、
.Net Framework付属のcscでコンパイルし実行できます。
特別な環境がなくても動くあたりは素晴らしい。

4.perlの場合(ファイル入出力はやっぱり速い。Pythonでは性能が出ない時はperlで実装)

1
2
3
4
5
6
7
8
9
10
use strict;
open my $r, '<:encoding(utf8)', 'in.txt';
open my $w, '>:encoding(utf8)', 'out.txt';
my $counter = 0;
while (<$r>) {
    $counter++;
    printf $w "%03d:%s", $counter, $_;
}
close $r;
close $w;

perlもシンプルに書けて良い。ただし、最近のredhatはperlがインストールされていない
こともあるので、必ずインストールされているPythonでツールを作ることが多くなった。
perl実行環境は、WindowsでもLinuxでもOracleがインストールされていると、その中に大概入っている。
そのperl実行環境を利用するのも良い。Oracleインストール領域に入っているので、perlからOracleに接続してDB操作するのも簡単。

python,java,c#はcloseの心配がない構文が用意されているのが良い。
perlはcloseを明示的に行う必要がある。
python,perlは目的のロジックに集中してコーディングができる。
Java,C#は定義部分が多くて。
VisualStudioやEclisepに頼って簡単にコーディングできたとしても、
メイン処理以外が多いのは、後から読んだ人にとってもメンテナンスしづらいかも。

同じタグの記事
同じカテゴリの記事

最近お気に入りの言語python

今まで、個人ツールで最も使っていたのはperlでした。perlは省略の美学というものがあり、暗黙変数を使いながら魔法のように処理が進むところが好きで、よくperlでツールを作っていました。ローカル写真の整理もperlスクリプトを作り、exifの撮影日時で写真のファイル名のリネームをしたりしていました。

しかし、最近の私のお気に入りはpython。確かに今風に使える。仕事ではJavaを使うことが多いので、Javaと似ているところも使いやすい。Threadなんて、Javaの昔のThreadにそっくり(pythonのThreadingはJavaのThreadの影響を受けているよう)。

日々覚えたpythonテクニックもこれからまとめていきたい。

同じタグの記事
同じカテゴリの記事