SQLALCHEMY是一个不可靠的方案。对于初级开发者而言,并不如SQL语句来得简明。sql
或者说,我不知道是否是全部的ORM数据库对象映射方案都存在这么一种状况。纯以开发逻辑而言。下述两段代码的结论是一致的:数据库
CODE1 : 正确实现session
partner_name
= request.args.get(
"partner_name")
site_name
= request.args.get(
"site_name")
delegation_query
= db.session.query(Delegation)
delegation_query
= delegation_query.\
filter(or_(
Delegation.grantee_id
== partner_id,
Delegation.grantor_id
== partner_id))
if site_name
is
not
None:
delegation_query
= delegation_query.\
join(Site, Site.id
== Delegation.site_id).\
filter(Site.name.like(
'%'
+ site_name
+
'%'))
if partner_name
is
not
None:
q1
= delegation_query.\
join(Partner, Partner.id
== Delegation.grantee_id).\
filter(Partner.name.like(
'%'
+ partner_name
+
'%'))
q2
= delegation_query.\
join(Partner, Partner.id
== Delegation.grantor_id).\
filter(Partner.name.like(
'%'
+ partner_name
+
'%'))
delegation_query
= q1.union(q2)
CODE2 : 错误实现学习
delegation_query
= db.session.query(Delegation)
if partner_name
is
not
None:
q1
= delegation_query.\
join(Partner, Partner.id
== Delegation.grantee_id).\
filter(Partner.name.like(
'%'
+ partner_name
+
'%'))
q2
= delegation_query.\
join(Partner, Partner.id
== Delegation.grantor_id).\
filter(Partner.name.like(
'%'
+ partner_name
+
'%'))
delegation_query
= q1.union(q2)
if site_name
is
not
None:
delegation_query
= delegation_query.\
join(Site, Site.id
== Delegation.site_id).\
filter(Site.name.like(
'%'
+ site_name
+
'%'))
delegation_query
= delegation_query.\
filter(or_(
Delegation.grantee_id
== partner_id,
Delegation.grantor_id
== partner_id))
另外附上这段代码的实现目标。partner为用户。site为资源。delegation为用户对资源的映射关系。spa
即:partner表保存用户的信息。site表保存资源信息。delegation表以ID为映射字段保存资源和用户的对应关系。设计
此处,delegation的做用是,一个用户将本身拥有的资源的权限部分开放给其余用户。对象
从系统使用者的角度考虑,输入的参数为:用户名称,资源名称。另一个默认的参数是从登陆状态中取得的,当前用户的ID。(查询权限控制)资源
因为实现模糊匹配的须要。这块的判断逻辑以下:开发
1. 当资源名称输入不为空,须要将关系表和资源表进行链接,实现经过名称查询资源。文档
2. 当用户名称输入不为空,须要将关系表和用户表进行链接,实现经过名称查询资源。
3. 为了执行条件2.须要确认关系表和用户表以哪一个键进行链接。(因为受权的关系,关系表中有两列外键对应用户表ID。一个是资源全部者,一个是受权的目标用户)
4. 为了执行条件3.因为部分数据库彷佛不支持FULL JOIN。所以采用UNION进行联合查询。
5. 查询除了上述1-4条件的基本逻辑外,必须知足这个条件:用户或者是具备了使用该资源的权限,或者是该资源的全部者。
从赋值角度考虑,以及过往的使用方法来看。SQLALCHEMY是支持串行操做的。可是CODE1和CODE2生成的SQL语句是不一样的。
实际中,CODE2实现的功能,已知在资源名称和用户名称都有输入值的状况下,忽略了资源名称条件,查询告终果。且未知的状况是,是否知足了条件5的设计。
这件事情来看,不论结果是不是我自身代码写法风格的问题。至少这样来看。并非简单的串联问题。
所以对当前阶段是否应该使用SQLALCHEMY产生了怀疑。至少若是使用ORM类初期,对于ORM封装内部的逻辑不了解的状况下,这件事情是不可靠的。
也许有文档说明这个问题,也许没有。不过至少上述这么一点问题是须要关注的,除此之外,对于ORM编写的SQL的调优,难度会更高。
总不能每次都用print(str(sql))的方式来解决问题吧。虽然这就是学习方法。。。