1

次の ndb モデルがあるとします。

class MyModel(ndb.Model):
    x = ndb.StringProperty()
    y = ndb.StringProperty()
    z = ndb.StringProperty(repeated=True)

上記のモデルのクエリを作成し、それを実行して結果を取得するメソッドがあります。ただし、このクエリを他の機能に変更したいと考えています。具体的には、次のとおりです。

def method_a():
    qry = MyModel.query() 
    values = {'query':qry}
    method_b(**values)
    entities = qry.fetch()

def method_b(**kwargs):
    k = ['a', 'b', 'c']
    qry = kwargs['query']
    qry.filter(MyModel.z.IN(k))

問題は、Query オブジェクトが不変であるため、method_b で変更できないことです。また、コードの特定のアーキテクチャに基づいて、method_b から新しいクエリを method_a に返すことはできません。

前述の機能を別の方法で実現する方法についてのアイデアはありますか??

更新:以下に示すように、私のコードのアーキテクチャを確認してください:

まず、構成ファイルで、モジュールのリストと、それらが有効かどうかを指定します。これらのモジュールは、実行したいクエリのフィルターに影響を与えます。

testparams = {
    'Test1': True,
    'Test2': True,
    'Test3': False,
    'Test4': True
}

次に、コードのどこかに、適切なモジュールが実行された後にクエリを作成するメソッドがあります。したがって、次のようになります。

def my_func():
    qry = MyEntity.query()

    # modules
    query_wrapper = [qry]
    values = {'param':'x', 'query_wrapper':query_wrapper} #other values also
    execute_modules(**values)
    # get query and add some more things, like ordering
    entities = query_wrapper[0].fetch()

execute_modules機能は次のとおりです。

def execute_modules(**kwargs):
    for k in config.testparams:
        if config.testparams[k]:
            if kwargs['param'] == 'x':
                (globals()[k]).x(**kwargs)
            elif kwargs['param'] == 'y':
                (globals()[k]).y(**kwargs)

最後に、表示モジュールは次のようになります。

class Test1():
    @classmethod
    def x(cls, *args, **kwargs):
        qry = kwargs['query_wrapper'][0]
        # do some stuff like adding filters
        kwargs['query_wrapper'][0] = qry

このアーキテクチャをより良いアプローチに変更するための提案はありますか?

4

3 に答える 3

1

method_b参照されているパラメーターを返すか変更せずにこれを行う方法を私は知りません。パラメータを使用してクラスを渡すなど、参照によって変数を渡す手法を使用する必要があります。

于 2012-09-26T04:01:06.703 に答える
1

dict/list などの参照オブジェクトで引数を渡すことができます。

def modify_query(kwargs):
  kwargs['qry'] = kwargs['qry'].filter(MyModel.z.IN(k))

qry = MyModel.query()
kwargs = {'qry': qry}
modify_query(kwargs)
result = kwargs['qry'].fetch()

これは、達成したいことを達成するための非常に汚い方法であることに注意してください。同様に、たとえば 1 つのオブジェクトを含むリストを渡す場合、そのリストの内容を (代入によって) 変更して、オブジェクトを変更できます。

def modify_query(list_object):
  list_object[0] = list_object[0].filter(...)
于 2012-09-26T07:41:20.253 に答える
0

オブジェクトを他のオブジェクトに置き換えるためのハックを行うことができます。例えば:

def f(args):
  qry = args[0]
  qry_new = qry.filter(Model.a == 2)
  args[0] = qry_new

qry = Model.query()
args = [qry]
f(args)
qry = args[0]
于 2012-09-25T22:43:26.320 に答える