zoukankan      html  css  js  c++  java
  • 关于SQLALCHEMY之(一)

    SQLALCHEMY是一个不可靠的方案。对于初级开发者而言,并不如SQL语句来得简明。

    或者说,我不知道是不是所有的ORM数据库对象映射方案都存在这么一种情况。纯以开发逻辑而言。下述两段代码的结论是一致的:

    CODE1 : 正确实现

      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为用户对资源的映射关系。

    即: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))的方式来解决问题吧。虽然这就是学习方法。。。

  • 相关阅读:
    全文本的检索
    网卡配置
    linux解压命令
    Session
    swoole安装
    Linux 系统磁盘满处理方法
    php写入和读取文件内容
    PHP读取文件夹的文件列表
    php 公历农历互相转换
    PHP实现RESTful风格的API实例
  • 原文地址:https://www.cnblogs.com/ranyuu/p/7326274.html
Copyright © 2011-2022 走看看