4

私は、MVCパラダイムに従ってアプリケーションを設計している最中です。私はsqlalchemy式言語(ormではなく)を使用しており、興味があればピラミッドを使用しています。

したがって、システム上のユーザーを表すユーザークラスの場合、avatar_url、name、aboutな​​どのさまざまなデータに対するいくつかのアクセサーメソッドがあります。db(でユーザーを検索するgetuserというメソッドがあります。名前またはIDで)、users行を取得し、それをuserクラスでカプセル化します。

ただし、ユーザークラスを作成するたびにこのルックアップを作成する必要がありますか?ユーザーが自分のコントロールパネルを表示していて、アバターを変更したい場合、xhrを送信するとどうなりますか。ユーザーオブジェクトを作成し、取得したデータを使用しない場合でもユーザー行を検索する必要があるのは無駄ではありません。しかし、単に列のサブセットに変更を加えたいですか?i / oが正しいのを待っているため、インデックスを作成しているにもかかわらず、このルックアップが無視できるとは思えませんか?

より一般的には、データベースにクエリを実行し、すべてのモデルクラスのデータをロードして変更を加える必要があるのは非効率的ではありませんか(小さなデータでも)。

個別のフォームクラスを作成し(すべての変更は何らかのフォームを介して行われるため)、特定のフォームクラスにそれらを継承させ、これらのセッターメソッドを実装する必要があると考えています。どう思いますか?

例:クラス:フォーム<-クラス:Change_password_form <-関数:change_usr_pass

適切なデザインを作成するためのアドバイスをいただければ幸いです。ありがとうございます。

4

2 に答える 2

3

SQLAlchemy ORMには、タスクを簡素化するいくつかの機能があります。ORM レイヤーに既に存在するかなりの車輪を再発明する必要があるようです:ユーザークラスと一緒に」 - これが ORM の機能です。

  • ORM では、他のものとは別に、ORM オブジェクトのキャッシュとして機能するセッションがあるため、トランザクションごとに同じモデルを複数回ロードすることを避けることができます。とにかく、リクエストを認証するために User オブジェクトをロードする必要があることがわかるでしょう。そのため、テーブルをまったくクエリしないことはおそらく選択肢ではありません。

  • 一部の属性を遅延ロードするように構成することもできます。これにより、ほとんど必要のない、またはかさばるプロパティは、それらにアクセスしたときにのみロードされます。

  • リレーションシップを 1 つのクエリで積極的に読み込むように構成することもできます。これにより、何百もの小さな個別のクエリを実行する必要がなくなります。つまり、現在の設計では、以下のコードが開始するクエリの数は次のとおりです。

    for user in get_all_users():
        print user.get_avatar_uri()
        print user.get_name()
        print user.get_about()
    

あなたの説明から、1 + (num_users*3) クエリが必要なようです。SQLAlchemy ORM を使用すると、単一のクエリですべてをロードできます。

結論としては、主キーによってデータベースから単一のオブジェクトを取得することは、かなり安価な操作であり、facebook のサイズのものを構築していない限り、心配する必要はありません。心配する必要があるのは、1 つの大きなクエリで十分な数百の小さな個別のクエリを作成することです。これは、SQLAlchemy ORM が非常に優れている領域です。

さて、「ユーザーオブジェクトを作成し、取得したデータを使用していないときにユーザー行を検索するのは無駄ではありませんが、単に列のサブセットに変更を加えたいだけです」-私は理解していますあなたは次のようなことを考えています

class ChangePasswordForm(...):

    def _change_password(self, user_id, new_password):
         session.execute("UPDATE users ...", user_id, new_password)

    def save(self, request):
         self._change_password(request['user_id'], request['password'])

class ChangePasswordForm(...):

    def save(self, request):
         user = getuser(request['user_id'])
         user.change_password(request['password'])

前者の例ではクエリを 1 つだけ発行し、後者では SELECT を発行してユーザー オブジェクトを作成し、次に UPDATE を発行する必要があります。後者は「2 倍効率的」に見えるかもしれませんが、実際のアプリケーションではその違い無視できるほどのものです。さらに、多くの場合、検証 (新しいパスワードは古いパスワードと同じにすることはできません)、権限チェック (ユーザー Molly は写真 #12343 の説明を編集することを許可されていますか?) を行うために、とにかくデータベースからオブジェクトをフェッチする必要があります。ロギング。

余分なクエリを実行することの違いが重要になると思われる場合 (何百万人ものユーザーが常にプロフィール写真を編集している場合)、プロファイリングを行ってボトルネックがどこにあるかを確認する必要があります。

于 2012-09-24T00:47:04.327 に答える
0

SOLIDの原則を読み、質問に答えるSに特に注意を払ってください。

ユーザーの存在チェックを実行する単一のクラスを作成し、その機能を必要とする任意のクラスに挿入します。

また、ユーザーのデータを格納するためのデータ永続性クラスを作成する必要があります。これにより、データベースを毎回照会する必要がなくなります。

于 2012-09-23T05:05:14.863 に答える