読者です 読者をやめる 読者になる 読者になる

SQLAlchemyで"case"

SQLAlchemyでcase文がつかえる。

case文とかこれのこと。 CASE WHEN 条件 THEN 値1 ELSE 値2 END

第一引数は必須で、条件と、それが真だった場合に返す値のタプルのリスト。

キーワード引数 else_ は偽だった場合に返す値。

条件にはand、or演算が使えることは確認した。

IN も使えるかと思ったけどどうも想定どおりの挙動ではない。後で調査。

from sqlalchemy.sql.expression import case, and_, or_

年齢から成人・未成年を出力する例。

session.query(
    Person.id,
    Person.name,
    case([(Person.age >= 20, "成人")], else_="未成年")
)

年齢・性別から結婚可能かどうか出力する例。

session.query(
    Person.id,
    Person.name,
    case([or_(and_(Person.age >= 16, Person.sex == "female"), and_(Person.age >= 18, Person.sex == "male")), "結婚可"], else_="結婚不可")
)

例としてはわかりやすいけど、妙な法律だねえ。

SQLAlchemy のサブクエリ

サブクエリのフィールドが見つからないといわれてちょっとハマった。

複数のカゴの中にりんごが複数入っているとする。
すべてのカゴに入っているりんごの総数を集計するサブクエリは以下のように書ける。

りんごのID (apple_id) と総数 (total) をフィールドとしてもたせる。

apple_in_bucket = session.query(
    AppleInBucket.apple_id,
    func.sum(AppleInBucket.count).label("total")
).group_by(
    AppleInBucket.apple_id
).subquery()

この時、apple_in_bucket.apple_idとしてもAttributeErrorを吐く。
サブクエリのフィールドにアクセスするには、cというフィールドを経由する必要がある。
(c はcolumnsの略らしい。もっといいインターフェイスはなかったのだろうか。)
apple_in_bucket.c.totalでりんごの総数をめでたく取得できる。

Djangoでリクエストがajaxかどうか判定する

これだけ

def index(request):
    request.is_ajax()
    return HttpResponse()

wordpressを既存のものからコピーで立ち上げる

いつも忘れるのでそろそろ記録を残しておく。

環境

すでにこの環境で動いているWordpressサイトが1つあるとする。

やりたいこと

すでに動いているWordpressをうまくコピーして、新しいサイトを立ち上げる。テーマやプラグインは引き継ぐが、記事やカテゴリなどのコンテンツは引き継がない。

手順

  1. php-fpmの設定ファイルを追加
  2. nginxの設定ファイルを追加
  3. mysqlにユーザーとデータベースを追加
  4. wordpressのディレクトリをコピー
  5. wp-config.phpを設定
  6. php-fpm, nginxの再起動

php-fpmの設定ファイルを追加

/etc/php-fpm.confに include するディレクトリを指定している。そこに既存の設定ファイルがあるはずなのでコピーする。

cp old_fpm.conf new_fpm.conf

pool名とポート番号だけ最低限書き換える。

new_fpm.conf

- [old_site]
+ [new_site]

- listen = 127.0.0.1:9001
+ listen = 127.0.0.1:9002

nginxの設定ファイルを追加

nginxの設定ファイルのディレクトリに既存の設定ファイルがあるはずなのでコピーする。

cp old_nginx.conf new_nginx.conf

ドメイン、ドキュメントルート、ポート番号だけ書き換える。

new_nginx.conf

     - server_name old_env;
     + server_name new_env;
     - root old/wordpress
     + root new/wordpress
  
     location ~ \.php$ {
         - fastcgi_pass   127.0.0.1:9001;
         + fastcgi_pass  127.0.0.1:9002;
     }
}

mysqlにユーザーとデータベースを追加

> create database new_wp_db default character set utf8mb4;
> grant all privileges on new_wp_db.* to wp_db_dev@localhost identified by 'hogehoge';

wordpressのディレクトリをコピー

wp-config.phpを含むディレクトリをまるごとコピーする。

cp -r old_wordpress new_wordpress

wp-config.phpを設定

データベース情報を書き換える。

define('DB_NAME', 'new_wp_db');
define('DB_USER', 'wp_db_dev');
define('DB_PASSWORD', 'hogehoge');

キーやソルトを書き換える。

php-fpm, nginxの再起動

$ sudo /etc/init.d/php-fpm restart
$ sudo /etc/init.d/nginx restart

再起動でOKが出たら、ブラウザからアクセスする。設定画面が表示されていたらおしまい。

wordpress上で画像の編集ができない

環境

現象

Wordpressのライブラリから画像が編集・保存できない。

原因

gdという画像処理用のライブラリがphpから利用できないことが原因だった。

対策

必要なライブラリをインストールするだけ。

$ sudo yum --enablerepo=remi,remi-php56 install gd-last, t1lib
$ sudo yum --disablerepo=* --enablerepo=remi,remi-php56 install php-gd

Pythonでプラットフォームごとに処理を切り替える

プラットフォームで処理を切り替えたいことがたまにある。

sysモジュールを使うと割と簡単にできる。

import sys

# "darwin", "linux", "win32" or "cygwin"
sys.platform

# Pythonのパスを取得したい場合は
sys.executable

PythonでスタンドアロンなGUIアプリを作る

Mac Yosemite 上に構築する。

下準備

Homebrewのインストール

クロスプラットフォームGUIアプリを作るためにQtというライブラリを利用する。

Qtをインストールするのにbrewコマンドが必要となる。

Homebrew

このページの先頭にあるスクリプトをコピーしてターミナル上で実行する。

virtualenvのインストール

GUIアプリを作るには大規模なpythonライブラリのインストールが必要となるので、

既存の環境にあれこれインストールして汚したくない。

python環境を目的に合わせて切り分けられるvirtualenvをインストールする。

sudo pip install virtualenv virtualenvwrapper

vitualenv環境作成

mkvirtualenv pygui
workon pygui

必要なもののインストール

  • Qt4
  • PySide
  • py2app

Qt

QtはクロスプラットフォームGUIアプリケーションが作成できるライブラリ。

Qt4とQt5があるが、QtをPythonから扱うためのPySideが現在Qt5に対応していないため4を使う。

brew install -v qt

PySide

QtをPythonから扱うためのライブラリ。

PyQtというライブラリもあるが、ライセンスの観点からはPySideの方が使いやすい。

先ほど作ったvirtualenv環境の中で、

pip install -v PySide

を実行する。

PySideのインストールには10分ほど時間がかかる。

進捗を見えやすくするために-vオプションを指定している。

続いてPythonにPySideのライブラリの場所を教える。

これをしないとimport時にエラーになる。

export DYLD_LIBRARY_PATH="$HOME/.virtualenvs/pygui/lib/python2.7/site-packages/PySide"

py2app

Pythonで書いたスクリプトスタンドアロンなアプリケーションとしてまとめるためのライブラリ。

他にはPyInstallerが似たような機能を提供しているが、Cで書かれたライブラリを扱う時にはpy2appの方が便利。

pip install py2app

サンプルアプリを作ってみる

cd ~
git clone git@github.com:PySide/Examples.git
cd ~/Examples/examples/dialogs
py2applet --make-setup findfiles.py
python setup.py py2app -A
open ./dist/findfiles.app

PySideのサンプルアプリが多数収録されたレポジトリがあるのでクローンする。

その中にファイルを検索するスクリプトが含まれているので、それが動いたらOK。