【MySQL】後からunique制約を付与する

何度もググっていたので。

alter table some_table add unique (some_field);

ちなみに、複数のフィールドの組み合わせで重複除去したい場合は以下。

alter table some_table add unique (some_field1, some_field2);

参考

MySQL で後からユニークインデックスを追加するには - tilfin's note

シリコーンハイドロゲル素材コンタクトレンズを選ぶ上での自分用まとめ

コンタクトを使い始めてから3年ぐらい経過したわけですが、その間2weekのレンズに関しては一貫して同じものを使い続けてきました。
たまに1dayを使ってはいたものの、コスパ的な問題から殆ど使わなくなりました。

このたびレンズの購入に際して、せっかくなので今までのレンズとは異なるレンズを買ってみようかと調べ出したところ、レンズ事情が想像以上に複雑怪奇だったため、後々のことも考慮してメモしておきます。

レンズの種類

初めに、今回対象とするコンタクトレンズの種類を定義しておきたいと思います。

今回購入の選択肢として挙がっているのは、

という上記3条件を満たしたものとなります。

コストの問題から1dayは不可、また一日の装用時間の問題からシリコーンハイドロゲル素材は譲れない要件です。

レンズ選択のポイント

シリコーンハイドロゲル素材レンズの取捨選択を行う上で注視すべき点は、酸素透過率含水率のようです。
基本的には、酸素透過率は高く、含水率は低いレンズが良いようです。
ただ含水率に関しては装用感にも関わってくるようなので、個人の好みに依存するかもしれません。

現在使用中のレンズ

何はともあれ、現在使用中のレンズについて記しておきます。

メダリスト フレッシュフィット コンフォートモイスト

現在使用しているレンズは、ボシュロム製のシリコーンハイドロゲル素材レンズである、メダリスト フレッシュフィット コンフォートモイストです。

f:id:taka_say:20150712202455j:plain
メダリスト フレッシュフィット コンフォートモイスト|ボシュロム・ジャパン

酸素透過率 含水率
130 36%

初めて眼科を受診した際に処方されたレンズを現在まで継続使用していました。
インターネットでの評判は可もなく不可もなく……といったところでしょうか。
特段良いレンズというわけではなさそうです。
自分としてもそこまでの不満があるわけではないものの、夕刻からの目の乾きが気になるようになってきたこともあり、このたびのレンズチェンジに踏み切ったという感じです。
酸素透過率、含水率ともにシリコーンハイドロゲル素材としては標準的な水準です。

候補のレンズ

当初の3条件を踏まえた上で購入候補をいくつか挙げていきます。

2WEEKメニコン プレミオ

f:id:taka_say:20150712214138j:plain
2WEEKメニコン プレミオ|コンタクトレンズのメニコン

酸素透過率 含水率
161 40%

国産メーカーであるメニコンが販売しているシリコーンハイドロゲル素材のレンズです。
2weekのレンズとしては最高の酸素透過率を誇り、安定した性能が望めそうです。
メニコン!というアナウンスが特徴的なCMもよく目にします。
コンタクトレンズ界のユリウス・カエサルといったところでしょうか。

アキュビュー オアシス

f:id:taka_say:20150712214608j:plain
アキュビュー® オアシス® | アキュビュー®

酸素透過率 含水率
147 38%

お次はJohnson & Johnsonが販売しているアキュビューオアシスです。
ワンデーアキュビュー云々というCMをよく目にします。
酸素透過率は2WEEKメニコン プレミオには及ばないものの、上々の値を保っているようです。
悪くはないですが、これを買うのであれば2WEEKメニコン プレミオでいいような気が。価格差もそこまでないようですし。
どうでもいいですが、Johnson & Johnsonがジョンソネジョンソンに聞こえる感じが好きです。
チャーチル枠。

エア オプティクス EX アクア

f:id:taka_say:20150712214601j:plain
1ヵ月交換終日及び連続装用ソフトコンタクトレンズのエア オプティクス® EX アクア

酸素透過率 含水率
175 24%

脅威の酸素透過率を誇る1monthのシリコーンハイドロゲル素材レンズ。
この高い酸素透過率と、低い含水率から、

エア オプティクス® EX アクアは、その高いクオリティにより、定期交換レンズで初めて、最長1ヵ月の連続装用が承認されたレンズです。 ※眼科医の指導は必要

という意味不明なスペックを誇ります。
一般的な2weekコンタクトレンズと比較すると割高感は否めないですが、それを補って余りある性能を保持しています。
1monthということで、使用途中に紛失・破損等した際のダメージが大きいのは気になるところ。
圧倒的すぎる性能は、女帝エカテリーナを彷彿とさせます。

エアオプティクス アクア

f:id:taka_say:20150712223708j:plain
ツーウィーク(2week)コンタクトのエア オプティクス® アクア | 2週間使い捨てソフトコンタクトレンズのエア オプティクス®

酸素透過率 含水率
138 33%

エア オプティクス EX アクアの兄弟分ともいえるレンズ。
若干含水率が低いこと以外はこれといった特徴はなさそうです。
特筆すべきインパクトがない様が、ビスマルクといったところでしょうか。

バイオフィニティ

f:id:taka_say:20150712214931j:plain
2週間交換コンタクトレンズ バイオフィニティ® |クーパービジョン | コンタクトレンズ

酸素透過率 含水率
160 48%

2WEEKメニコン プレミオに次ぐ酸素透過率を誇るシリコーンハイドロゲル素材レンズです。
含水率がかなり高い点が気になります。
このバイオフィニティ、目に張り付いて取れないことで有名らしいです。
ちなみに2weekということで販売されていますが、米国内で1monthで販売されているレンズと同じ製品らしく、人によっては1month装用する方もいるらしいです。
そのせいかお値段が割高な感じは否めません。
パッケージがバイオな感じなのは好印象です。
なんとなくですが、ワイナ・カパックなイメージのレンズでしょうか。

レンズ性能まとめ

各レンズの酸素透過率と含水率をまとめておきます。

酸素透過率 含水率
メダリスト フレッシュフィット コンフォートモイスト 130 36%
2WEEKメニコン プレミオ 161 40%
アキュビュー オアシス 147 38%
エア オプティクス EX アクア 175 24%
エアオプティクス アクア 138 33%
バイオフィニティ 160 48%

以上、5種類のシリコーンハイドロゲル素材レンズをチェックしました。
あくまで酸素透過率と含水率というデータから判断するならば、バランス重視の2WEEKメニコン プレミオ、装用感重視のバイオフィニティ、目の保全性重視のエア オプティクス EX アクア(リッチ!)といった感じでしょうか。

洗浄液の罠

ところで2weekや1monthのコンタクトレンズでは洗浄が必須ですが、ここに思いもよらぬ罠が潜んでいました。
実はシリコーンハイドロゲル素材のレンズには洗浄液による相性があるらしく、相性の悪いもので洗浄を行ってしまうと、角膜ステイニングが起こってしまうらしいのです。
角膜ステイニングが起こると、角膜障害のリスクが増大してしまうため、可能な限り避けるべきです(許容可能なリスクであるとの指摘もあります)。
というわけで以下がレンズと洗浄液の組み合わせによるリスク表です。
基本的に値が高いほど危険性が高いことを示しています。

f:id:taka_say:20150712234725j:plain
※ エア オプティクス EX アクアは海外名がNight & Dayなため、表最下段のものです。

今我が家にストックされている洗浄液はというと……

f:id:taka_say:20150712235414p:plain

ボシュロム製のレニューです。
2WEEKメニコン プレミオ等は表に記載されていませんが、どうやらレニューは基本的にシリコーンハイドロゲル素材のレンズと相性が悪いようです……。

というわけで……。

まとめ

今回最終的に選ばれたレンズは、レニューと比較的相性の良い、

f:id:taka_say:20150712214931j:plain
バイオフィニティ となりました。
かなりのレニューストックが眠っているという個人的事情から、今回は洗浄液による相性問題が起きてしまうレンズたちは諦めました。

バイオフィニティが自分の目にマッチすることを祈りつつ、ひとまずコンタクトレンズ談義は終了とします。

参考

シリコーンハイドロゲル素材のコンタクト一覧|使い捨てコンタクトレンズ通販ガイド
シリコーンタイプコンタクトレンズ|コンタクトレンズのエースコンタクト
シリコーンハイドロゲル対応のオススメ洗浄液|使い捨てコンタクトレンズ通販ガイド
StainGrid.com

【Python3】データがstrではなくbytesで返ってくる問題【MySQL】

PyMySQL3を使ってDB内のデータ取得をしたところ、varchar型に設定されたカラムのデータがbytes型で返ってきてしまう問題に遭遇。
後々のためメモ。

環境

Python 3.4.3
MySQL 5.6
PyMySQL3

解決策

PyMySQL3への接続とクエリは以下のような平凡なものである。

import pymysql

conn = pymysql.connect(params)
cur = conn.cursor()
cur.execute("SELECT id, name from some_table")
result = cur.fetchone()
print(result['name'])

ここでnameカラムがvarchar型だと、<class 'bytes'>として値が返ってきてしまった。

この問題を解決するためには、DBで定義されているカラムのcollation(照合順序)を変更する必要がある。

現在のcollationを確認するにはmysqlに接続、DBを選択し、

show table status;

を実行すればよい。

Name: some_table
(略)
Collation: utf8_bin

上記のように、collationがutf8_binになっているのがbytes型でデータが返却される原因のようだ。
というわけで下記を実行。

ALTER TABLE some_table COLLATE utf8_general_ci;
ALTER TABLE some_table MODIFY COLUMN name VARCHAR(255) CHARACTER SET `utf8` COLLATE `utf8_general_ci`;

これでカラムの設定と既存のデータがutf8_binからutf8_general_ciに変更された。

pythonに戻り再度実行すると、データがstrで返って来ていることが確認出来るはずである。

参考

python - PyMySQL returns bytes instead of str - Stack Overflow
馬場誠Blog(東京都世田谷区経堂のWebクリエイター)» ブログアーカイブ » 照合順序をutf8_general_ciからutf8_unicode_ciへ変更する

【Python3】HTMLのエスケープされた記号を元に戻す

環境

Python 3.4.3

方法

xml.sax.saxutilsモジュールのunescapeメソッドを使えばOK。

from xml.sax.saxutils import unescape
text = '&amp; &lt; &gt;'
print(unescape(text))  # => '& < >'

第二引数にdictを与えると、独自辞書の定義も可能とのこと。

from xml.sax.saxutils import unescape
text = '&lt;ルイズ貧乳&gt;'
unescape(text, {'貧乳': 'かわいい'})  # => '<ルイズかわいい>'

参考

19.11. xml.sax.saxutils — SAX ユーティリティ — Python 2.7ja1 documentation
236:HTMLをエスケープする

【Python3】sqlite3.ProgrammingError: Incorrect number of bindings supplied【SQLite3】

また引っかかりそうなのでメモ。

環境

Python 3.4.3
sqlite3

解決策

executeメソッドSQLを実行しようとしたところ、

sqlite3.ProgrammingError: Incorrect number of bindings supplied.

と怒られてしまいました。

原因は単純で、executeメソッドの第二引数の形式です。
executeメソッドでは、第二引数はタプルで指定する必要が有るため、以下のようになります。

name = 'some_user_name'

# 駄目な例
c.execute('select * from users where name=?', name)

# 正しい例
c.execute('select * from users where name=?', (name,))

指定する変数がひとつの場合、最後に余計なカンマが付着するため若干気持ち悪いですが、Pythonの文法規則上やむを得ないですね。

【MySQL】データアップデート時に自動で時刻を更新する

フルスタックのWebアプリケーションフレームワークだと自動でやってくれますが、小規模フレームワークだと自力でやらねばならないためメモ。

CREATE TABLE some_tabel (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `modified` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
);

これでcreatedには新規に作成された時の時刻が、modifiedにはupdateされる度にその時刻が挿入されます。

【CentOS6】鍵認証によるssh接続

ローカルのMacからリモートのCentOSへ鍵認証でssh接続するための手順をメモっておきます。
公開鍵および秘密鍵は予め作成が済んでいるものとします。

環境

Mac OS X Yosemite
CentOS 6.6

鍵の設定

まずはローカルMacからリモートに公開鍵の送付。

scp ~/.ssh/id_rsa.pub some_user@xxx.xxx.xxx.xxx:~/.

次にリモートのCentOSにログインし、公開鍵の設定を行う。

mkdir ~/.ssh  # .sshディレクトリがない場合
mv ~/id_rsa.pub ~/.ssh/.
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

次にsshd_configの修正。

sudo emacs /etc/ssh/sshd_config

各行のコメントアウトを外し、AuthorizedKeysFileでは公開鍵の場所の指定をする。

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      ~/.ssh/authorized_keys

またパスワード認証は不要なので、PasswordAuthentication noに設定する。

以上終了後sshdの再起動。

sudo service sshd restart

ローカルMacに戻り、sshログイン。

ssh -i ~/.ssh/id_rsa some_user@xxx.xxx.xxx.xxx

無事鍵認証でssh接続成功!

ついでにローカルMacのconfigファイルにssh接続の設定を追記。

emacs ~/.ssh/config
Host some_host
  HostName xxx.xxx.xxx.xxx
  User some_user
  port 22
  IdentityFile ~/.ssh/id_rsa

上記設定追記後、下記コマンドでssh可能。

ssh some_host

面倒な入力がなくなって便利!

参考

RSA公開鍵認証によるssh接続設定について(Macbook -> VPS) - Qiita

【CentOS6】新規ユーザーの追加とsudo権限の付与

環境

CentOS 6.6

ユーザー作成と権限付与

各コマンドはsudo権限のあるユーザーで実行する。

またsudoは、wheelグループに属しているユーザーのみ可能という方針で行う。
visudoコマンド単体で/etc/sudoersの編集は可能だが、/etc/sudoersの下部に記載されている#includedir /etc/sudoers.dによって、/etc/sudoers.d/下のファイルが読み込まれるため、ここでは/etc/sudoers.d/下に新規で設定ファイルを作成し、そのファイルに設定を記載する。
ちなみに#コメントアウト的な意味ではないので注意。

まずはユーザーの追加とパスワードの設定。

$ sudo useradd hoge
$ sudo passwd hoge

次にsudo権限の付与。

$ visudo -f /etc/sudoers.d/wheel

当たり前だが、emacsではなくviで開くので注意。
下記設定を新規記載。

%wheel ALL=(ALL) ALL

wheelユーザーに権限付与。
文法ミス等してしまうと、sudoコマンドが実行不可になってしまう危険があるので注意。visudoで開いており、警告を出してくれるはずなので大丈夫だとは思われる。

最後にユーザーをwheelグループに追加。

$ sudo usermod -G wheel hoge

新しく作ったユーザーに変更し、sudoが必要なコマンドを実行してみる。

$ su hoge
$ sudo visudo
[sudo] password for hoge

無事sudo権限を持ったユーザーの作成に成功!

参考

CentOS - sudoできるユーザを制限する。 - Qiita
CentOS - sudoers は編集せずに sudoers.d の中に設定を書こう - Qiita

【MeCab】Python3で解析時にbuiltins.UnicodeDecodeError【Flask】

Twitterから取得したデータをMeCabで処理し、Flaskを用いたWebアプリケーション上で表示しようとしたところ、下記のようなエラーが出現。

builtins.UnicodeDecodeError
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfc in position 0: invalid start byte

もしかしたらまたハマるかもしれないので念のためメモ。

環境

Python 3.4.3
MeCab 0.996

解決策

原因は不明だが、エラーメッセージを見るにエンコーディングがどうので死んでしまう模様。
ちなみにMeCabの実装コードは下記のような感じ。

import MeCab
mecab = MeCab.Tagger()
node = mecab.parseToNode("私はルイズが好きです。なぜなら、彼女はとてもキュートだからです。")
while node:
    print(node.surface)
    node = node.next

中々解決策に辿りつけなかったのだが、一行追記することでエラーの回避が可能に。
原因は正直良くわからない。
修正したコードは以下。

import MeCab
mecab = MeCab.Tagger()
mecab.parse('')  # これを追記!
node = mecab.parseToNode("私はルイズが大好きです。なぜなら、彼女はとてもとてもキュートだからです。ルイズかわいい!")
while node:
    print(node.surface)
    node = node.next

元々Python3でMeCabparseToNodeメソッドを使用すると、最初に返されるnodeが空の値というバグがあり、この解決のためにmecab.parse('')をするらしいのだが、UnicodeDecodeErrorへも対策として効果を発揮してくれた。

原因はよく分からないが、動くようになったので取り敢えず良しとする。

参考

Ubuntu14.04とPython3でMeCabを使う方法 | トライフィールズ