2017-06-21 72 views
-1

我有一个关于SQLAlchemy的问题。SQLAlchemy中Where子句

目前我有使用瓶两种型号 - 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' 

生成的查询:

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" = ? 

有与查询的最后一个probleme ,但我不知道是否

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()的呼叫目标的最后一个实体。

因此,在您的情况下,它会提取Module的id属性并添加过滤标准Module.id == <some value>。修复取决于您的请求参数。

也因为Query.first()可能会返回无,您应该以某种方式说明这一点。

action = Action.query...first() 

if action: 
    return jsonify(action.serialize) 

else: 
    # Handle not found 
+0

谢谢。 这是我目前使用的请求。 但它不是指定模块操作的过滤器。 –

+0

这可能是,但在你的例子中,请求参数字典有一个key * id *,然后用你当前的代码从Module中提取出来。我忘了在Query.first()中完全可以返回None的答案中加入,你应该为此做好准备。你真的应该在问题中添加这样的细节。现在完全不清楚request.args实际上是什么以及除了观察到的效果之外。 –