flask tutorialのDBにMongoDBを使う
flaskを勉強中。
flaskのtutorialを写経するだけではなーと思い、
tutorialではDBにsqlite3 を使っているところ、MongoDBを使ってみた。
以下備忘兼ねて、ハマったところなどメモ
PyMongoでCollectionをJoinするとき
tutorialのblog.py 36行目にて以下SQLでJoinしている箇所
post = get_db().execute( 'SELECT p.id, title, body, created, author_id, username' ' FROM post p JOIN user u ON p.author_id = u.id' ' WHERE p.id = ?', (id,) ).fetchone()
MongoDBでCollectonのjoinのやり方が分からず結構苦労した。
MongoDBでJoin相当の処理を実行する場合はaggregateメソッドを使用して同等の処理ができるらしい。
参考は以下
pymongoのAggregation Examplesを見ても$lookupなどの記載はなかったが、 ここのCollectionに関しての記載を読む感じ、行けそうだったので試してみたところ問題なく実行できた。
コードは以下
posts = db.post.aggregate([ {"$lookup": { "from":"user", "localField":"author_id", "foreignField":"_id", "as":"userInfos" } }, {"$unwind":"$userInfos"}, {"$sort": { "updated" : -1 }}, {"$project": { "id": "$_id", "title":"$title", "body": "$body", "updated": "$updated", "author_id": "$author_id", "username":"$userInfos.username", } } ])
取得した後、listに格納し直した上でrender_templateで変数を渡しているのだけど、
もっとスマートなやり方があるような気がする。。
pymongoでfind_oneメソッドにて_idでfilterする場合は
ObjectIdでなきゃ駄目
それ以上でも以下でもないが、、
以下はNGで
g.user = get_db().user.find_one({'_id': user_id})
以下はOK
g.user = get_db().user.find_one({'_id': ObjectId(user_id)})