2

データベース モデル クラスには、パラメータ化された SQLSELECTステートメントを実行する多くのメソッドがあります。これらのクエリのほとんどにはWHERE、結果をフィルター処理するフィールドを持つ句が含まれています。デフォルトの場合、すべての結果を取得するために where 句の比較を無視します。例:

def get_notes(self, pcb_serial_no, note_type=None):
    ''' Get notes recorded against a PCB unit, optionally filtered by note_type. '''
    cursor = self.db.execute('''
        SELECT pcb_serial_no, note_type, description, username, note_time
        FROM pcb_notes_view
        WHERE pcb_serial_no=?
            AND COALESCE(?, note_type)=note_type
        ''',
        (pcb_serial_no, note_type,)
    )
    rows = cursor.fetchall()
    return len(rows) > 0 and rows

Noneデフォルトの引数値(にマップNULL) との組み合わせを使用していますCOALESCE。これは、読みやすさのためにこれまでに考えられた最良の解決策です (もちろん主観的です) が、この「既定のパラメーター」は一般的な要件であり、それを実装するためにどのような慣用的な方法があるのか​​ 疑問に思いましたか? COALESCEまた、特にその列がインデックス化されていない場合、デフォルトのケースでパフォーマンスが大幅に低下するかどうかもわかりません。

4

1 に答える 1

2

残念ながら、コメント システムは例を投稿するのには適していませんが、SQLAlchemy には生の SQL へのほぼ 1:1 のマッピングがあり、このアプローチは文字列操作からステートメントを作成するよりも優れていると思います。ですから、これは答えというよりもコメントです。ご容赦ください。

関数の ORM スタイルを書き換えると、次のようになります。

def get_notes(self, pcb_serial_no, note_type=None):
    ''' Get notes recorded against a PCB unit, optionally 
        filtered by note_type. '''
    q = sql.select([
            pcb_notes_view.pcb_serial_no, 
            pcb_notes_view.note_type, 
            pcb_notes_view.description, 
            pcb_notes_view.username, 
            pcb_notes_view.note_time
        ]).where(
            pcb_notes_view.pcb_serial_no==pcb_serial_no
        )
    if note_type is not None:
        q = q.where(pcb_notes_view.note_type==note_type)
    rows = q.execute().fetch_all()
    return len(rows) > 0 and rows

ORM を使用するとクエリの再利用が非常に簡単になり、ORM はテーブル間の関係を推測できるため (参照整合性を備えたデータベースの場合)、ビューの代わりに ORM クエリを定義する傾向があります (SQLSoup からのビューのマッピングにはもう少し作業が必要です)。優れた IDE (私は PyCharm を使用しています) からのスマートなオートコンプリートと組み合わせると、ORM の生産性が大幅に向上します。

しかし、それは好みの問題です。ストアド プロシージャを使用して、すべてのロジックをデータベースに移動することもできます。

于 2013-06-14T01:58:59.790 に答える