我对SQLAlchemy有疑问。
目前我有两个使用Flask的模型 - 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')
使用Flask,我尝试使用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" = ?
查询结束时出现问题,但我不知道是否
action = Action.query.join(Module).filter(Module.id == module_id).filter_by(**request.args.to_dict()).first()
是否正确。
答案 0 :(得分: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>
。修复程序取决于您的请求args的用途。
另外因为Query.first()
可能会返回None,你应该以某种方式解释它。
action = Action.query...first()
if action:
return jsonify(action.serialize)
else:
# Handle not found