2017-06-21 15 views
-1

SQLAlchemyについて質問があります。SQLAlchemyのwhere節

現在、私はフラスコを使用して2つのモデルを持っている - SQLAlchemyの:フラスコで

class Action(db.Model): 

    __tablename__ = 'ACTION' 

    _FIELDS_LABELS = ("ID", "MODULE_ID", "CATEGORY", "LABEL", "COMMAND", "ARGS", "FILE_ID") 
    _REPR_FIELDS = ("MODULE_NAME", "FILE_NAME") 

    id = db.Column(_FIELDS_LABELS[0], db.Integer, primary_key=True) 
    module_id = db.Column(_FIELDS_LABELS[1], db.Integer, db.ForeignKey('MODULE.ID')) 
    category = db.Column(_FIELDS_LABELS[2], db.String()) 
    label = db.Column(_FIELDS_LABELS[3], db.String()) 
    command = db.Column(_FIELDS_LABELS[4], db.String()) 
    args = db.Column(_FIELDS_LABELS[5], db.String()) 
    file_id = db.Column(_FIELDS_LABELS[6], db.Integer(), db.ForeignKey('FILE.ID')) 

    file = db.relationship('File') 

class Module(db.Model): 

    __tablename__ = 'MODULE' 

    _FIELDS_LABELS = ("ID", "NAME") 

    id = db.Column(_FIELDS_LABELS[0], db.Integer, primary_key=True) 
    name = db.Column(_FIELDS_LABELS[1], db.String(), unique=True) 
    actions = db.relationship('Action') 

私はそのようなURLでアクションを取得しよう:だから

http://ip:port/modules/0/actions/18 

を私はアクション青写真:

action_blueprint = Blueprint('action', 
          __name__, 
          url_prefix="/modules/<string:module_id>/actions") 

とルート:

@action_blueprint.route('/', methods=['GET']) 
def read_all(module_id): 

    if module_id == '*': 
     if len(request.args) == 0: 
      actions = Action.query.all() 
      return jsonify(list_to_json(actions)) 
     else: 
      try: 
       action = Action.query.filter_by(**request.args.to_dict()).first() 
       return jsonify(action.serialize) 
      except InvalidRequestError as i: 
       return json_response(400, "InvalidRequestError : {}".format(i.args)) 
    else: 
     try: 
      module = Module.query.get(module_id) 
     except AttributeError as a: 
      return json_response(400, "'{}' needed to be '*' or a number.".format(module_id)) 

     if len(request.args) == 0: 
      return jsonify(actions=list_to_json(module.actions)) 

     action = Action.query.join(Module).filter(Module.id == module_id).filter_by(**request.args.to_dict()).first() 
     return jsonify(action.serialize) 

しかし、私次のエラーがあります。

AttributeError: 'NoneType' object has no attribute 'serialize' 

生成されたクエリ:クエリの端部とproblemeが

SELECT "ACTION"."ID" AS "ACTION_ID", "ACTION"."MODULE_ID" AS "ACTION_MODULE_ID", "ACTION"."CATEGORY" AS "ACTION_CATEGORY", "ACTION"."LABEL" AS "ACTION_LABEL", "ACTION"."COMMAND" AS "ACTION_COMMAND", "ACTION"."ARGS" AS "ACTION_ARGS", "ACTION"."FILE_ID" AS "ACTION_FILE_ID" 
FROM "ACTION" JOIN "MODULE" ON "MODULE"."ID" = "ACTION"."MODULE_ID" 
WHERE "MODULE"."ID" = ? AND "MODULE"."ID" = ? 

あり、私は本当に知りません

action = Action.query.join(Module).filter(Module.id == module_id).filter_by(**request.args.to_dict()).first() 

が正しいかどうか

答えて

1

問題は、生成されたクエリを見るといくらか明らかです。

WHERE "MODULE"."ID" = ? AND "MODULE"."ID" = ? 

は、両方の値が同じでない限り、何らかの不一致があることを示す必要があります。その場合、述語は冗長です。それは

request.args.to_dict() 

が原因でこれが明確である

{ 'id': <some value> } 

のような辞書を生成することが明らかであるかQuery.filter_by()作品:

式は、クエリの主要な実体から抽出されたキーワード、 またはQuery.join()へのコールの対象となった最後のエンティティ。

あなたのケースでは、モジュールのID属性を抽出し、フィルタリング基準Module.id == <some value>を追加します。この修正は、リクエスト引数が何であるかによって異なります。

Query.first()もNoneを返す可能性があるので、どういうわけかそれを考慮する必要があります。

action = Action.query...first() 

if action: 
    return jsonify(action.serialize) 

else: 
    # Handle not found 
+0

ありがとうございました。 これは私が現在使用しているリクエストです。 しかし、それは指定されたモジュールのアクションに関するフィルタではありません。 –

+0

これは可能かもしれませんが、あなたの例では、要求引数dictにはキー* id *があり、これはModuleから現在のコードで抽出されます。 'Query.first()'がNoneを返す可能性があるので、すべての答えを追加するのを忘れました。あなたは本当にそのような詳細を質問に加えるべきです。今、request.argsが実際にどのようなものであり、何のために、観察された効果以外のものが完全に不明です。 –