ActiveRecord、Postgres 和分区表
我根据 pg 文档 此处:。基本上,我有一个父表和几个子表。父表上的插入触发器会将父表上的任何插入重定向到适当的子表中——这效果很好。
然而,ActiveRecord pg 适配器似乎依赖于 postgres INSERT ... RETURNING "id" 扩展来获取初始插入后返回行的 id。但触发器似乎破坏了 RETURNING 子句——尽管行已正确创建,但没有返回 id。
虽然我认为这种行为是有道理的——毕竟,主表中没有插入任何内容,我确实需要找到某种解决方法,因为将插入其他需要刚刚插入的行 ID 的子记录排。
我想我可以在插入之前向行添加某种唯一的 id,然后在插入后使用此键重新读取它,但这看起来相当混乱。有人有更好的解决方法吗?
I've set up a trigger-based partitioning scheme on one of our pg 8.3 databases according to the pg docs here:. Basically, I have a parent table, along with several child tables. An insert trigger on the parent redirects any inserts on the parent into the appropriate child table -- this works well.
The ActiveRecord pg adapter, however, seems to rely on the postgres INSERT ... RETURNING "id" extension to get the id of the returned row after the initial insert. But the trigger seems to break the RETURNING clause -- no id is returned, although the row is created correctly.
While I suppose this behavior makes sense -- after all, nothing is being inserted in the main table, I really need to find some kind of work-around, as other child records will be inserted that require the row id of the just-inserted row.
I suppose I could add some kind of unique id to row prior to insert and then re-read it using this key after insert, but this seems pretty kludgy. Does anyone have a better work-around?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从 Rails v.2.2.1 开始,您只需覆盖 PostgreSQLAdapter 中的 #supports_insert_with_returning 方法即可关闭“返回 id”行为。
Since Rails v.2.2.1, you can turn off 'returning id' behavior just by overriding #supports_insert_with_returning method in PostgreSQLAdapter.
目前看来我最好的选择是只更改 before_create 事件中的表前缀,以便插入直接发生在底层分区表上,完全绕过插入触发器。然而,这不是一个完美的解决方案,但似乎是最高效且最简单的。
我能想到的唯一其他解决方案是向每个表添加一个 guid 列,并在插入后立即通过 guid 重新读取分区表中的行以获取 id。
欢迎任何其他建议。谢谢——米
Currently it looks like my best option is to just change the table prefix in a before_create event so that the insert happens on the underlying partition table directly, bypassing the insert trigger altogether. This is not a perfect solution, however, but seems to be the most performant and the simplest.
The only other solution I can come up with is to add a guid column to each table, and re-read the row from the parition table by guid immediately after insert to get the id.
Any other suggestions are welcome. Thanx -- m