DB操作でORMを使うことの是非について
qiitaでこんな記事があったのでちょっと考えてみる
ORMのメリット
- 動的にwhere句を簡単に安全にかける
- 可読性が高い(保守しやすい)
- PostgreSQLとMySQLが混在するような環境でも同じ書き方ができる
ORMのデメリット
- 最適化する時にはやはり生の方が便利
- 生クエリーを知らなくてもかけるため、技術的な知識が身に付きにくい
- 生クエリーでないと実現できない場合がある
少し比較
単純なクエリー
orm 有り(django)
shops = Shops.objects.filter()
orm 無し(MySQL-pythonライブラリ使用)
sql = 'SELECT * FROM shops'
cursor.execute(sql)
cursor.fetchall()
これはそれほど変わらない
動的にwhere句を生成する時
例えば、idとkeywordによって検索条件を指定してリストを出力する時
idは一致検索、keywordは含むかどうかで判定する
orm 有り(django)
shops = Shops.objects.filter() if "id" in requests.GET: shops.filter(id=requests.GET["id"]) if "keyword" in requests.GET: shops.filter(keyword__in=requests.GET["keyword"])
orm 無し(MySQL-pythonライブラリ使用)
sql = 'SELECT * FROM shops' wheres = [] sql_args = [] if "id" in requests.GET: wheres.append('id = "%s"') sql_args.append(requests.GET["id"]) if "keyword" in requests.GET: wheres.append('keyword LIKE "%s"') sql_args.append(requests.GET["keyword"]) sql += " WHERE "+" and ".join(wheres) if len(wheres) > 1 else "" cursor.execute(sql, sql_args) cursor.fetchall()
この例だと動的生成はORM利用の方がしやすいと思う
ただ、自分たちで動的に生成しやすいようなclassを作って管理するとか方法はあるかもしれない
速度が問題となるケースは生クエリー
例えばslowqueryが出てる時に手動でチューニングする場合
joinの順番やorderの仕方などをqueryを視覚的に認知しながら組める点は生query有利
また、ormはループしながら単発のqueryを叩いているときがあるなど、非効率な動きをしてることがある
こんな時、生ならquery一発でもってきて後から精査できる
また、サブクエリー等を含んだ複雑な条件式もORMで組むより生の方が見やすく、書きやすいことも多い
最後に
個人的には共存していけばいいじゃないの と思う
それぞれ得手不得手があるのだから、全部ORMとか生にこだわる必要はないと思う
自分はほぼORMで速度上の問題がある時や、複雑なクエリーを汲む時だけ生でやってます