Slick で 複数のカラムを同時にアップデートする方法
表題の件が、パッと見てもわからなかったので調べたのでメモ。
GitBucketのバグ修正で、とあるカラムをとあるカラムと同様に更新するというコードを書いたのですが、同時に更新する方法がさっとわからなかったので、それぞれのカラムを別々のクエリで更新するというしょうもないことをしてしまったので、反省を込めてメモ。(せっかくなんでリリースに間に合わせたくてとりあえずバグが直ってて動くことを優先した・・・)
Before
def updateCommitIdTo(owner: String, repository: String, issueId: Int, commitIdTo: String): Unit = Query(PullRequests).filter(_.byPrimaryKey(owner, repository, issueId)).map(_.commitIdTo).update(commitIdTo) def updateCommitIdFrom(owner: String, repository: String, issueId: Int, commitIdFrom: String): Unit = Query(PullRequests).filter(_.byPrimaryKey(owner, repository, issueId)).map(_.commitIdFrom).update(commitIdFrom)
After
def updateCommitId(owner: String, repository: String, issueId: Int, commitIdTo: String, commitIdFrom: String): Unit = Query(PullRequests).filter(_.byPrimaryKey(owner, repository, issueId)) .map(pr => pr.commitIdTo ~ pr.commitIdFrom) .update((commitIdTo, commitIdFrom))
多分あってるはず。
言葉で説明すると、 map で更新するカラムを選択するが、単一カラムでない場合は、~
でつなげたオブジェクトを返す必要があり(.map(pr => pr.commitIdTo ~ pr.commitIdFrom)
)、updateで値を設定する際には、タプルで渡す。
ちなみに、ググるまでもなく初めからGitBucketのリポジトリの中に答えがあったとうオチもある。当たり前だけどまずはそこのコード読むだけで自分がやりたいことは大体そこに答えがある。素敵なことです。 SlickのQueryは今回初めて読み書きしましたが、結構面白い書き方するんで、もっといろいろ遊んでみたくなりますね。
去年はScalaとか構文すらほぼ忘れてるレベル(Javaもあやうい)だったので、ここ半年ちょいいいトレーニングになったなと思い返してみる。
積もり積もった下書きまとめ
ちょっと気を抜くと半年近く更新してないという残念な状態に。。。
下書きに未完成品やタイトルだけ決めたものがいろいろ積み残ってしまったので、いつかかけるといいなと思いつつ、もう書かない気がするのでここにダンプする。
古い順に。。。
- Omnibusを使用して/opt 以下に一式を入れるdeb/rpmパッケージを作成する
- Chefのrpmパッケージに憧れて、Omnibusを使用して、gitbucketをjdk込のオールインワンパッケージを作ってみようとした話。
- JDKのインストールすらも面倒だろ?と。あとサービス化してくれてたほうが嬉しいやんと。
- OpenJDKのビルドが面倒でほぼ挫折。Omnibusは面白いのでいつか何かで使えるといいな。 https://github.com/opscode/omnibus-ruby
- Copy to clipboard ボタンを作れる ZeroClipboardを使ってみた
- GitBucketに Copy to clipboard を追加してみたので、その時使った ZeroClipboardを紹介しようと思っていました。ごめんなさい。
- OpenStack keystoneにabを仕掛けるメモ
- OpenStack の Python 3対応に関するメモ
- ただの趣味で調べていたので・・・
- eventletとか どうなるんかね?何か進展したのかなぁ。eventlet楽しいよね。ノンブロッキングだけどブロック!
- python testr fixtures によるUnit Test
- これも趣味で。正直結構そそられたけど、並列化とか考えるほどのUTを書くことはなさそう。
- Keystone PKI Tokenの仕組み
- なんか暇な時にソースを読んだので。なんかメモ書きしようと思った。脳内にしかなかったので完全にロスト!
- eventlet backdoor 経由で heapy 使って ヒープダンプとかしチャオ!
- とか思ってた日もありました。
- Amazon EC2のインスタンスを復旧する
- Apache MINA sshdと jgitを使って、オレオレ gitリポジトリサーバを作ろう!
その他自分で下書き読んでも、なんでそれ書こうとしたのか思い出せない奴は永久に削除しました。
Git の http proxy に関するまとめ
この記事は、Git Advent Calendar 2013 の21日目の記事です。
前日(20日目)の記事は、@harupong さんの Get Great Pro Git !! です。
Pro Gitのサイトは、git関連のことでググると大体行き着くので、よく見てましたが、書籍だったんですね。それを無償公開で、さらには継続的に更新されているとは・・・。また、日本語翻訳は非常にありがたいので感謝感謝です。
Gitでは、ローカルレポジトリとリモートレポジトリ間のデータ転送(clone/push/pull/fetchなど)用のプロトコルに、Local、ssh、git、httpの4つが使用できます。
圧倒的にsshやgitを使用するケースが多かったように思いますが、最近ではGitHubもhttpsプロトコルが clone URLのデフォルトになっているようにみえます。 これは企業等のファイアウォール内から使用する人にもGitが普及してきたという事かもしれません。 私も http proxyサーバを経由せねば外部にアクセス出来ない環境にいることがあるため、SSHなどの利用に不自由することが多いです。
そこで私のように社内LAN等から http proxy サーバ経由で Gitレポジトリを扱わねばならぬ人のためのまとめです。
ちなみに、git http proxy でググると git config --global http.proxy
の話がすぐ見つかるので、それプラスアルファのまとめです。
ほとんどの人にとってそれだけで十分ですw
環境変数を使用する
GitはUNIX環境でよくある http_proxy/https_proxy 環境変数が使えます。
$ export http_proxy=http://proxy.example.com:8080 $ export https_proxy=$http_proxy $ git clone https://github.com/tanacasino/dotfiles.git
認証付きのproxyを利用している場合は、ユーザ名とパスワードは以下のように設定できます。
$ export http_proxy=http://<username>:<password>@<hostname>:<port>
$HOME/.gitconfig
に書く毎回 環境変数を指定するのは面倒ですし、bashrcなどに http_proxy を書くと proxyを使ってほしくないツールにも影響が出るので記載したくない。 そんな時は
$HOME/gitconfig
にhttp.proxy
を設定します。$ git config --global http.proxy http://proxy.example.com:8080 $ cat $HOME/.gitconfig ... [http] proxy = http://proxy.example.com:8080
これで git clone/push/fetch/pull/ls-remote などの使用時に自動的に proxyを使用してくれます。 ちなみに、http/https の両方のケースで
http.proxy
を使用してくれるのでhttps.proxy
の設定は不要です。 というか、https.proxy
という設定はGit的に存在しないように見えます。REPOSITORY/.git/config
に書く$HOME/.gitconfig
で設定すると、そのユーザで git を使う際のすべてに影響します。 例えば、GitBucket やGerrit といった、httpプロトコルでGitレポジトリを提供するアプリケーションを社内LANに設置している場合、$HOME/.gitconfig
に書いたhttp.proxy
の設定のせいで、社内のレポジトリを使用する際も、proxy を経由してしまいます・・・。通常ですと、 no_proxy を設定すればええんやー!と考えるかもしれませんが、 残念ながら git では no_proxy という設定がなく使用できません。
このような場合は、
$HOME/.gitconfig
に書くのをやめて、各レポジトリの.git/config
に proxyを設定することで回避できます。$ mkdir dotfiles $ cd dotfiles $ git init $ git config --local http.proxy http://proxy.example.com:8080 $ git remote add origin https://github.com/tanacasino/dotfiles.git $ git fetch
これで、レポジトリ毎に proxyを設定できるので、社外(eg. GitHub, BitBucket)、社内(eg. GitBucket, Gerrit)のgitレポジトリを使うといった混在環境でも困りません。
REPOSITORY/.git/config
で リモートレポジトリ毎に proxy を設定する3番までで完璧と思いきや gitではリモートレポジトリを複数設定できますので以下のように、社外のレポジトリと社内のレポジトリの両方をみるレポジトリを使うことがあります。(いや私だけかもしれませんが。。。)
私の場合は、GitHubに置いてある dotfiles 群のうち、仕事向けに完全に特化する内容(ユーザ名・メールアドレスやproxyのための設定など)を GitHub にpushするのは怒られそうな気がするので、社内業務の設定は、社内の GitBucketレポジトリに pushして、その他の修正を受け取るために、upstream レポジトリとして GitHub を使用しています。
# 以下のように origin がLAN内のGitBucket、upstreamがGitHub $ git remote -v origin https://192.168.32.10/gitbucket/git/tanacasino/dotfiles.git (fetch) origin https://192.168.32.10/gitbucket/git/tanacasino/dotfiles.git (push) upstream https://tanacasino@github.com/tanacasino/dotfiles.git (fetch) upstream https://tanacasino@github.com/tanacasino/dotfiles.git (push) # この場合は、 globalに http.proxyを設定するわけにもいかず。。。
さて、このような場合は no_proxy を使うんや!そうや絶対そうやー!と思いますが、no_proxy はありませんので、諦めます。 このようなケースでは、
REPOSITORY/.git/config
でリモートレポジトリ毎に proxy を設定します。$ cd dotfiles $ vim .git/config [remote "origin"] # ここにも proxy が書けるんだぜ!!! # 以下のように空白にしておけばproxyを使用しない proxy = [remote "upstream"] # 以下は、http.proxy を設定している場合は不要ですが載せておきます # proxy = http://proxy.example.com:8080
これで、リモートレポジトリが外部・内部にわかれててややこしい感じでも問題なっしんぐ!
no_proxyを使えるようにしてみる
長々といろいろな http proxy 設定してきましたが、3番以降の問題はGitが no_proxyを使えない!という話です。 とりあえず無理やり追加してみました。
私はC言語の読み書きはできませんので
http.proxy
の設定部分のコードのコピペだけで作ってみました。 誰か詳しい人が upstream向けにパッチを作ってくれるんじゃないかという期待。使用方法は以下の通り。prefix 等はいい感じに自分の環境でどうぞ。CentOS6.4でもビルドできましたが手順はどっかいっちゃいました。
# Ubuntu 12.04でのビルド手順 $ sudo apt-get build-dep git $ wget http://git-core.googlecode.com/files/git-1.8.4.3.tar.gz $ tar xzf git-1.8.4.3.tar.gz $ cd git-1.8.4.3 # apply patch $ wget https://gist.github.com/tanacasino/7528954/raw/0ca5bf774a88189ffaca9bf69917d6c29130eb9e/git-1.8.4.3-noproxy.patch $ git apply git-1.8.4.3-noproxy.patch # build and install $ ./configure --prefix=$HOME/local/packages/git-1.8.4.3-noproxy $ make $ make install $ $HOME/local/packages/git-1.8.4.3/bin/git --version git version 1.8.4.3 # gitconfig [http] proxy = http://proxy.example.com:8080 noproxy = localhost,192.168.32.10
このように http proxyの設定1つだけでも、いろいろあって楽しめますね!
明日22日目は、@kozyty さんの記事になります。お楽しみに! Git Advent Calendar 2013
日本OpenStackユーザ会 第16回勉強会に行ってきました
というわけで参加報告するまでが勉強会ということで。
まずはじめに勉強会の準備・会場の準備をしていただいた方、発表者の方、お疲れ様です。 本当にありがとうございました。
では、私の記憶と手元のメモを晒します。 意外とメモが役に立たなくてなんのメモかもう思い出せない・・・ あと、発表者が言ったことなのか?自分の感想・メモなのかが思い出せない・・・
誰かこれを読んで間違いに気づいた方いれば教えて下さいませ。
勉強会について
- Site: http://connpass.com/event/4064/
- 日時: 2013/11/24 (Sun) 13:00〜17:00
テーマ
- novaのソースコードリーディング
- havana 2013.2
資材
-
- https://github.com/openstack/nova
- GitHubにソースあるしご自由に準備してくださいとのことでしたが、講師の @boot_vmlinuz さんが、GNU Globalを使用したHTML資材を準備してくれいました
発表スライド
内容
発表スライド読んだほうが正しいですが、なんとなく。
- ディレクトリ構造
- nova-* のブートストラップ
- RPC(プロセス間通信)
- DB
- 定期実行処理(Periodic Tasks)
ディレクトリ構造 編
発表スライドに書いてます。こんなメモよりそれを見るのが正解。
何となくとっていた and スライドに書いてない気がする メモをとりあえず
- hacking : なんだっけ?知ってる人います?に誰も反応せず
- objects
- サービス間のデータ受け渡し用(RPC)
- instance_id とか渡してたけど、それだとinstance_id使ってDBの情報を引くことになる。DBへの負荷高いから、objects の objects に突っ込んで渡そうになっているとのこと
- servicegroup: 死活監視
- 昔は DBで管理してた
- それは負荷が高い
- 死活監視をモジュール化した。DB以外使える
- 3種類
- DB
- zookeeper
- memcacched
- DBドライバは @boot_vmlinuz さんが書いたから不具合あれば教えてくださいとのこと
- storage: ストレージ操作関連 multipathとかも
この辺でファイルの話もあったけどなぜかメモも記憶も飛んでいる・・・
requirements.txt
etc に設定ファイルにサンプルあるのでのぞいてみる
- 設定の数は超絶多いとのこと
- @ishikawa84g さんがエクセルにまとめてくれているそうな
nova.conf.sample をExcelの表にしたものです http://t.co/asfKbduv1z #opst16
— ishikawa84g@魔法中年 (@ishikawa84g) 2013, 11月 24
nova-* プロセスのブートストラップ編
- プロセスのエントリーポイントとなるコードは、nova/cmd/*.py ですよ
- 昔は、binディレクトリ以下にあったけど変わった
- setup.cfg でスクリプトになるように書かれてる
簡単なサンプルとして nova/cmd/consoleauth.py を見てみた。
novaは3種類に分けれるよん
- 単一プロセスのサービス
- nova-consoleauthなど。ここが多い
- 複数プロセスのサービス
- nova-conductor
- workers で設定できる
- RESTful APIサービス
- nova-api
nova/cmd/*.py
から始まりソースを順番に読む。このあたりで、迷子の参加者多数。
そしてなぜか自分のメモがここだけ だぜ口調。
- nova.service.Service の解説だぜ
- nova.service.Service.create で作るんだぜ
- つまりは、 nova-compute だけ db_allowed=False だぜ
- nova-compute はDBアクセス禁止だぜ
- 今までDBからとっていたような情報が欲しい場合は、nova-conductor に問い合わせるぜ
この辺は1行ずつ読んで解説をしていただいたと思いますが、ソース追いかけてて断片的にしかメモがないので、記憶で読んだ気がするコードやキーワードを並べときます。
nova/cmd/*.py
nova/service.py
- class Service
- def create
- def start
nova/openstack/common/service.py
nova/manager.py
- def start の init_hostの話
- nova-computeの場合
nova/compute/manager.py
- additional_apisがあるのはのnova-conductorのみ(たぶん)
- post_start_hook は nova-cells だけ
- backdoor_port の話
- telnet 指定のportにつなぐと python のインタラクティブシェル使える
- http://eventlet.net/doc/modules/backdoor.html
RPC用 consumer の話
Sercice の startの解説で
- consumer 3つ
- topic = computeとかみたいにサービスの種類を表す
host = サービスが動作するホスト
topic and fanout=False : 複数ある同一topicのサービスのうち1つだけが、メッセージ受け取る
- topic.host and fanout=False : 自分宛てのメッセージを受け取る
- topic and fanout=True: topic関係者全員が受け取る
RPCの話
発表スライドの13枚目。
- サービスBのAPIでも rpcしないケースもあり。
- 例: DBみるだけのときなど
- RPC送信部 impl_kombuなど
nova/openstack/common/rpc/__init__.py
nova/openstack/common/rpc/amqp.py
nova/openstack/common/rpc/impl_kombu.py
- RabbitMQ
nova/openstack/common/rpc/impl_qpid.py
- Apache Qpid
nova/openstack/common/rpc/impl_zmq.py
- ZeroMQ
nova/openstack/common/rpc/impl_fake.py
- UnitTest向け。
- dispatcherにより適切なモジュールを呼び出し
- B/manager.py or baseapi.py
check_for_lock
- よくわかんなかった・・・
rpc の データのserialize/desirialize => MQに突っ込むために、JSON形式の文字列データにしたり、受信側でそれを pythonのプリミティブ型(int,str,dict,list)に戻したりする
nova/conductor/ 以下の例(スライド 14)
- manager.py nova-conductor 自身の本体
- api.py => 他のサービスからの nova-conductor の呼び出しコード
- rpcapi.py => 他のサービスからの nova-conductor のRPC呼び出しコード
おまけ編
- 中国のスパコンでOpenStack使われた話
- http://www.openstack.org/assets/presentation-media/How-to-Deploy-OpenStack-on-Tianhe-2-Supercomputer-2.pdf
DB呼び出し
スライド 16
サービスA => nova/db/api.py
=> nova/db/sqlalchemy/api.py
=> DB
- impl は sqlalchemy だけ。
- zookeeper かなんか別のドライバ作る?って話もあるとか。
- 作る話は止まってたけど、最近動き出した?みたいな話もありんすた
- DB操作のメソッドを追加する場合は、両方にメソッドを足しましょう
nova/db/api.py
nova/db/sqlalchemy/api.py
- すべての APIが context を渡すようになっている
periodic tasks
ユーザからのリクエストイベントからの処理じゃなくて、定期的に実行する処理。periodic_task
nova/openstack/common/periodic_task.py
nova/compute/manager.py
- デコレータがついてるやつがperiodic_taskになりんす
- @periodic_task.periodic_task
- いろいろあるよねーな話。ザクッと解説していただけましたがメモなし
- shelved => havanaからできた
- 停止に近い
- VMの定義を残したまま、ハイパーバイザー上のリソースを開放する
- デコレータに引数も付けれるよ
- interval を個別にコントールできたりする?
- spacing
まとめ
今日まだまだ読んでないところあるよん。virt のところとか。 でもまあプログラムのエントリーポイントとか、どこにコードがあるかわかったはずなので、今日の説明を足がかりに処理を追いかけれるよ。みんながんばれ。
その他宣伝
- クラウドマネジメントツール勉強会 第二回
- 12/4 水曜日
- みんなくるよね?
- OpenStack Advent Calendar 2013
- 小ネタでもなんでも歓迎
- Glance の代わりに Walrus を使おうとしている人や、イジメ抜く、許さない、絶対な人もいる
- 沖縄 OpenDays
- 沖縄でやる。丸一日は、OpenStackのみ。マジチャレンジャー。
- OpenStack Days Tokyo 2014
- 2/13,14
- 今年は二日間だから day ではなく days だよ
おしまい!意外とメモしてないとこ多いけどもう覚えてません! その他の情報は、 Twitter のハッシュタグ #opst16 でどうぞ。