Python3.4でMySQLに接続してDjangoでも使ってみる

2014-09-18
このエントリーをはてなブックマークに追加

MySQLドライバはどれを使えばいいのかはっきりわからない、というのがPython3に本格的に踏み込めないでいた一番の理由がだったわけですが、MySQL Connector/PythonがPython3をサポートしててDjangoでも使えてマルチバイト文字もちゃんと通るっぽかったので試してみました。

unzip mysql-connector-python-1.2.3.zip
cd mysql-connector-python-1.2.3
python setup.py install
pip freeze

インストールはこれだけ。
DB-API 2.0準拠らしいので触り方も変わらずに安心。こういうのがPythonのいいところじゃないかと。

import mysql.connector


def main():

    _conn = mysql.connector.connect(
            user='USERNAME',
            password='PASSWD',
            host='127.0.0.1',
            database='DBNAME')

    _cur = _conn.cursor()
    _cur.execute("select * from app_comment;")
    for _row in _cur.fetchall():
        print(_row[0])

    _cur.close()
    _conn.close()

if __name__ == '__main__':
    main()

DjangoからMySQLを使うときはこれで。

DATABASES = {
    'default': {
        'NAME': 'DBNAME',
        'ENGINE': 'mysql.connector.django',
        'USER': 'USERNAME',
        'PASSWORD': 'PASSWD',
    }
}

マルチバイト文字使ってもinsert,update、selectひと通り問題なさ気だったので試しになんか書いてみようと思いました。

あ、Djangoは1.7で試してます。

Djangoでsettings.pyを使い分ける

2014-02-07
このエントリーをはてなブックマークに追加

python manage.py –settings=project_name.dev_settings

まあこれだけの話なんですけど、知らないと意外と不便なので。

project_nameがDjangoの各自のプロジェクトの名前でmanage.pyと同一階層にプロジェクト名のフォルダがありまして、その中にdev_settings.pyという開発環境用の設定ファイルがある、という体でのお話でした。

project_name/
├── manage.py
├── project_name
│   ├── __init__.py
│   ├── dev_settings.py
│   ├── settings.py
│   ├── wsgi.py

こんな感じですね。

使い分けるのはこれしか方法がないわけじゃないんですけど、ハセテツはこんなやり方してますよ、というメモでした。

前は –settings=dev_settings だけでよかった気がしたんだけど、気のせいかな。Django1.6でのお話でした。

Tags: ,

Pythonでmultiprocessingを使って並列処理

2012-11-23
このエントリーをはてなブックマークに追加

メニーコア時代なのでPythonでもCPUいっぱい使いたいんですよ。まずはサンプルソース。Djangoのコマンドで使ったものから取ってきたのでmultiprocessingと関係ない部分もあります。

# -*- coding: utf-8 -*-

import multiprocessing
from multiprocessing import Process, Pool

from django.core.management.base import BaseCommand

def make_and_post(_file):
    print(_file)
    return True

class Command(BaseCommand):

    def main(self):
        _p = Pool(multiprocessing.cpu_count() / 2)
        print(_p.map(make_and_post, ['a', 'b', 'c', 'd']))

    def handle(self, *args, **options):
        self.main()

実行した結果の出力は以下

a
c
b
d
[True, True, True, True]

Poolでコア数/2を指定しているので、コア数の半分(i7のMBPだと4コアなので、半分で2になります)の並列処理ができます。

make_and_postをmapから呼んでいますが、make_and_postに渡されるのはリストではありません。リストの要素のひとつが渡されます。’a’とか’b’とかです。

make_and_postの返り値がTrue(失敗してればFalseでしょう)なので、_p.map()を出力するとTrueとかFalseが入ったリストになっています。

PythonにはGILというものがあり、フツーに書いてるだけでは一個のコアしか使ってくれません。32コアとかあっても働いてるのは1コアとかの残念な結果になりがちです。それが悪いとは言わないが、もっと頑張って欲しい時もあるんですよ。

上記サンプルはPython2.7.3で、MacOSXで動かしました。

これでGILの壁を超えるっ!

Tags:

Djangoで自作コマンドをmanage.py mycommandで実行する方法

2012-05-23
このエントリーをはてなブックマークに追加

Djangoでバッチファイルの実行をする方法です。

だいぶ前に「PythonでDjangoを使ったバッチ処理」で説明していますが、別のやり方です。というか、Djangoとしてはこっちが正しいんだと思います。

まずは任意のプロジェクトがあって、プロジェクトにappというアプリケーションが作成されているものとして進めます。

そこで、app(アプリケーションフォルダ)の下に「management」というフォルダを作成、中に__init__.pyを配置します。__init__.pyは空でいいです。

次に、managementフォルダの中に「commands」というフォルダを作成、またもやcommandsフォルダのなかに__init__.pyを配置します。もちろん、空で大丈夫です。

そして、commandsフォルダの中に「mycommand.py」を配置します。これが今回のメインになります。ここまでで以下の構成になっていると思います。

プロジェクトルート/
| app/
| | management/
| | | commands/
| | | | __init__.py
| | | | mycommand.py
| | | __init__.py
| | __init__.py
| | models.py
| | tests.py
| | views.py
| __init__.py
| manage.py
| settings.py
| urls.py

これでやっとバッチ処理が書けます。mycommand.pyを開いて、

#! /usr/local/bin/python
# -*- coding: utf-8 -*-

from django.core.management.base import BaseCommand

class Command(BaseCommand):

    def handle(self, *args, **options):
        print "hello command."

これでOK!

python manage.py mycommand

で実行できます。もちろんDjangoのmodelとかも触れます。*argsがあるから引数もOK!
こっちのほうがきれいにまとまりますね。

Python2.7、Django1.3.1で動作しています。試してませんが、もっと古いDjangoでも動くのではないかと。

Tags: ,

Djangoでjson出力してjQueryで受け取る方法

2012-03-13
このエントリーをはてなブックマークに追加

以前はxml出力してクライアントでパースしたり、htmlを出力してそのまま埋め込む、っていうやり方が多かったのですが、最近はjsonを多用しています。

from django.utils import simplejson
from django.core import serializers

def index(request):

_values = simplejson.dumps([{“key0”: “value0”, “key1″:”value1″}], ensure_ascii=False)
return HttpResponse(_values, mimetype=”application/json;charset=utf-8”)

出力するのはこれだけ。非常に簡単。

Django1.3、Python2.7です。Djangoは1.1でも動いた記憶が。Pythonは2.6以降かな。まぁ2.6以降っていってもjsonの取り扱いだけですけど。あ、Python3は知りません。

jQuery側は

$.getJSON(url, function(result, status){

alert(result[0].key0);
alert(result[0].key1);

});

これだけ。jQueryは1.6使ってます。

DjangoでFormのアトリビュートを実行時に指定する

2012-02-19
このエントリーをはてなブックマークに追加

同じフォームを複数の画面で使う場合、使う画面によって指定するcssのclassが異なるケースがあると思います。

そんな時、view側でフォームのインスタンスを生成した後でattrsを指定できると便利です。そんなサンプルです。

class EntryForm(forms.Form):

body = forms.CharField(widget=forms.Textarea())

こんなフォームがあったとして、viewで使うときには

_form = EntryForm()
_form.fields[‘body’].widget.attrs[‘class’] = ‘some_css_class’

です。これで

<textarea id=”id_body” rows=”10″ cols=”40″ name=”body” class=”some_css_class”></textarea>

こんな感じのHTMLが出力されます。

_form.fields[‘body’].widget.attrs[‘disabled’] = True

とかもできるので、シチュエーションによって使い分けられると思います。

Django1.3で試しましたが、1.0以降なら動くんじゃないかな?

Tags: ,

Djangoで実行されたSQLを確認する方法

2011-12-13
このエントリーをはてなブックマークに追加

ORM使っててなんか結果がいまいちなときは、どんなSQLが実行されたのか確認したくなるのが人情ってもんだと。

で、その方法です。

from django.db import connection
print connection.queries

これだけです。Django1.3でしか試してませんが、きっともっと古いのでも動くと思います。

Tags: , ,

GAEでwebappを使った場合とDjangoを使った場合のパフォーマンスを計測してみた

2011-07-28
このエントリーをはてなブックマークに追加

フレームワーク使うとモジュール等の読み込みでステップが増え、その分レスポンスが遅れます。これは必然です。

GoogleAppEngine(GAE)でwebappとDjangoを使った場合、どっちが速いのか。多機能になればなるほど遅くなりそうだから当然Djangoの方が遅いだろうが、どれくらいの差があるものか検証してみました。

webapp

def get(self):

path = os.path.join(os.path.dirname(__file__), ‘index.html’)
self.response.out.write(template.render(path, {‘now’:datetime.datetime.now() }))

Django

def index(request):

return render_to_response(‘index.html’, {‘now’: datetime.datetime.now() })

両方共テンプレートに現在時刻を書き出すだけ。いちいちテンプレートのパスを指定してるwebappが不利かな?それぞれ本番環境で5回ずつ計測(ApacheBench)して結果(Time per request、mean)は、

webapp

  1. 46ms
  2. 39ms
  3. 32ms
  4. 37ms
  5. 32ms

Django

  1. 39ms
  2. 33ms
  3. 32ms
  4. 32ms
  5. 44ms

大して変わんないという、驚きの結果でした。本番環境だとキャッシュが効くからフレームワークの重さなんて関係なくなるんですかね。これなら「多機能フレームワークは重いから」っていう理由でマイクロフレームワークを選択することはないかと。まぁこれだけの計測で結論出すのは尚早だとは思いますが。

webappはセッション使えないしFormもないので、そのへんの機能必要なのであればDjangoかな。まぁ速度変わらないのであれば全部Djangoでもいいんですけどね。あ、ちなみにDjangoは以前紹介したGoogle App Engine Helper for Djangoは使用しないで計測しました。

Google App Engine PythonでDjango1.2を使うまでの道のり

2011-07-22
このエントリーをはてなブックマークに追加

GoogleAppEngine(GAE)はPythonが使えるのでぜひ利用させていただくべしなのですが、ずっとDjangoありきで書いてきちゃったもんで、GAEでもDjango使いたいんです。しかも、1.2。

まぁ別にwebapp使えばいいだけの話なんですけど、やはり使い慣れたDjangoが一番ですよね。まぁDjangoじゃヘビーすぎるからもっと軽快にwebappやFlaskでいいじゃんっていうのもありますが。

Pythonは2.5、Djangoは1.2.5を使います。simplejsonも事前にインストールしておきましょう。AppEngineSDKのインストールとかはGoogleさんが詳しく説明してくれています。今回使ったSDKのバージョンは1.5.2。古いとDjango1.2は動かなかったりするようです。

Djangoでプロジェクトを作るときは「django-admin.py startproject hogehoge」ですが、今回は別の手法を取ります。「Google App Engine Helper for Django」という便利なものを使わせて頂きます。事前にダウンロードしておいてください。

  1. 例えば「guestbook」というアプリを作りたいという前提で進めます。任意の場所のguestbookというフォルダを作ります。中は空でいいです。
  2. そして、ダウンロードしてきたGoogle App Engine Helper for Djangoを解凍し、生成されたフォルダの中身をguestbookフォルダの中にコピーします。guestbookフォルダの直下にappengine_djangoフォルダがあればOK。
  3. app.yamlをテキストエディタで開き、一行目の「application: google-app-engine-django」を「application: guestbook」に書き換え、manage.pyとmain.pyの「InstallAppengineHelperForDjango()」を「InstallAppengineHelperForDjango(‘1.2’)」に書き換えます。まぁアプリケーション名と使用するDjangoのバージョンを書くだけですね。
  4. GoogleAppEngineLauncherを起動し、アプリケーションを登録します。新規じゃなくて、既存のアプリケーションを登録してください。ここではguestbookフォルダを選択するだけです。
  5. GoogleAppEngineLauncherでguestbookを選択、「Run」をクリック。左のアイコンが緑の矢印になったら起動成功です。「Browse」をクリックしてDjangoのいつもの「It workd!」が出たら成功!

長くなったので今回はここまで。アプリケーションの追加とかは後日続き書きます。というか、そっから先は普通のDjangoなので不要かな。

Djangoで動的な複数のOR検索を実装する方法

2011-06-28
このエントリーをはてなブックマークに追加

ORの数が決まっているならどうって事ないのですが、例えば複数キーワードを入力できるコンテンツ検索機能などを実装しようとすると意外と難しかったりします。

from django.db.models import Q
def search(request):

_words = (u’キーワードその位置1’, u’キーワードその位置2’)

queries = [Q(title__contains=word) for word in _words]
query = queries.pop()
for item in queries:

query |= item

_list = Entry.objects.filter(query)

キーワードのリストは検索フォームからPOSTされたものとしてください。個数は可変です。Entryというモデルに含まれるtitleというフィールドからの検索です。検索ワードが含まれるデータを検索しています。

で、ORでクエリをつないでいって、最後に検索しています。

Django1.2.3で実装、動作していますが、Qオブジェクトが使えるバージョンならどれでも動くと思います。

Tags: ,