使用 jsonb_array_elements 在 sqlalchemy 的 select_from 和 join 中。

huangapple go评论116阅读模式
英文:

Using jsonb_array_elements in sqlalchemy select_from and join

问题

我正在使用SQLAlchemy ORM,并尝试生成类似以下的PostgreSQL查询:

  1. SELECT resources.*
  2. FROM histories, jsonb_array_elements_text(histories.reported_resources) as report_resource_name
  3. JOIN resources ON resources.resource_name = report_resource_name
  4. WHERE histories.id = :id

到目前为止,我得到了这个:

  1. query = (
  2. select([
  3. Resource
  4. ])
  5. .select_from(
  6. History,
  7. func.jsonb_array_elements(History.reported_resources).alias('report_resource_name'))
  8. .join(Resource, Resource.resource_name == text('report_resource_name'))
  9. .where(History.id == 1)
  10. )

但是出现了错误:

InvalidRequestError: 无法确定要从哪个FROM子句加入,有多个可以加入到此实体的FROM子句。请使用.select_from()方法来建立明确的左侧,并提供一个明确的ON子句(如果尚不存在)以帮助解决歧义。

如何在SQLAlchemy的.select_from()中将资源表连接到jsonb_array_elements结果?

最小模型表和输入数据如下:

  1. class History(Base):
  2. __tablename__ = 'histories'
  3. id = Column(Integer, primary_key=True)
  4. reported_resources = Column(JSONB)
  5. class Resource(Base):
  6. __tablename__ = 'resources'
  7. id = Column(Integer, primary_key=True)
  8. resource_name = Column(String)
  9. Resource
  10. id | resource_name
  11. --------
  12. 1 | machine1
  13. 2 | machine2
  14. 3 | operator1
  15. 4 | operator4
  16. History
  17. id | reported_resources
  18. -------
  19. 1 | ['machine2', 'operator4']

请注意,我已经将代码中的错误History.id = 1修正为History.id == 1

英文:

I am using SQLAlchemy ORM and trying to figure out how to produce a PostgreSQL query like the following:

  1. SELECT resources.*
  2. FROM histories, jsonb_array_elements_text(histories.reported_resources) as report_resource_name
  3. JOIN resources ON resources.resource_name = report_resource_name
  4. WHERE histories.id = :id

So far I got this:

  1. query = (
  2. select([
  3. Resource
  4. ])
  5. .select_from(
  6. History,
  7. func.jsonb_array_elements(History.reported_resources).alias('report_resource_name'))
  8. .join(Resource, Resource.resource_name == text('report_resource_name'))
  9. .where(History.id = 1)
  10. )

But the error says:

> InvalidRequestError: Can't determine which FROM clause to join from, there are multiple FROMS which can join to this entity. Please use the .select_from() method to establish an explicit left side, as well as providing an explicit ON clause if not present already to help resolve the ambiguity.

How can I join the resources table ON the jsonb_array_elements result in .select_from() using SQLAlchemey?

Minimum model table and input data like following:

  1. class History(Base):
  2. __tablename__ = 'histories'
  3. id = Column(Integer, primary_key=True)
  4. reported_resources = Column(JSONB)
  5. class Resource(Base):
  6. __tablename__ = 'resources'
  7. id = Column(Integer, primary_key=True)
  8. resource_name = Column(String)
  9. Resource
  10. id | resource_name
  11. --------
  12. 1 | machine1
  13. 2 | machine2
  14. 3 | operator1
  15. 4 | operator4
  16. History
  17. id | reported_resources
  18. -------
  19. 1 | ['machine2', 'operator4']

答案1

得分: 1

我对ORM方言不太熟悉,但重写你的SQL语句可能有帮助:

  1. SELECT resources.*
  2. FROM histories
  3. CROSS JOIN LATERAL jsonb_array_elements_text(histories.reported_resources) AS rr(report_resource_name)
  4. JOIN resources ON resources.resource_name = rr.report_resource_name
  5. WHERE histories.id = :id

(在这种情况下,“LATERAL”关键字是可选的。)

参考:

英文:

I am not fluid with the ORM dialect, but it should help to rewrite your SQL statement as:

  1. SELECT resources.*
  2. FROM histories
  3. CROSS JOIN LATERAL jsonb_array_elements_text(histories.reported_resources) AS rr(report_resource_name)
  4. JOIN resources ON resources.resource_name = rr.report_resource_name
  5. WHERE histories.id = :id

(The LATERAL keyword being optional in this case.)

See:

huangapple
  • 本文由 发表于 2023年5月25日 11:04:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328651.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定