postgresql - 在 WITH 子句中链接 sql 查询以最终执行更新

标签 postgresql testing common-table-expression

我正在尝试用一堆对象填充测试数据库以进行非常具体的集成测试,但我无法使用其中一个查询返回的 ID 作为后续对象字段的值。

-- create a user with an account with salesforce integration
WITH p AS (
        INSERT INTO person (email, confirmed, first_name, last_name) VALUES
        ('test3@example.com', TRUE, 'Salesforce', 'Guy')
        RETURNING id
     ),
     ac AS (
        INSERT INTO account (subscription_type, subscription_expires_on, salesforce_integration) VALUES (0, '2024-10-10', TRUE)
        RETURNING id
     ),
     am AS (
        INSERT INTO account_member (person_id, account_id, admin) VALUES
        ((SELECT p.id FROM p), (SELECT ac.id FROM ac), TRUE)
        RETURNING account_id, person_id
     ),
     la AS (
        -- create a salesforce linked_account
        INSERT INTO linked_account (person_id, provider_id, access_token) VALUES
        ((SELECT p.id FROM p), 'salesforce', '00DC00000016x37!AQIAQIt5EpCIgTFl9hg2qF9Ed6vzLJmTg9Nrd.uxvVva5WaxzMChn4sBBgV6KXiICCBoJgcFYbrTqpFtFJwpd.B7fe5kG9_z')
        RETURNING id
    ),
     v AS (
        -- create a video and take
        INSERT INTO video (person_id, account_id) VALUES
        ((SELECT p.id FROM p), (SELECT ac.id FROM ac))
        RETURNING id
    ),
     t AS (
        INSERT INTO take (video_id, key, duration, state, thumbnail_selected) VALUES
        ((SELECT v.id FROM v), 'g1/g1546ad07eff44c397e356be7c4bea49/g1546ad07eff44c397e356be7c4bea49', 35, 2, 1)
        RETURNING id
    )
    -- update video with selected take
    UPDATE video SET selected_take_id = (SELECT id FROM take WHERE take.video_id=video.id);

我遇到的问题是,当测试运行时,它指出我创建的视频 (v) 没有设置 selected_take_id,这意味着底部的“使用所选镜头更新视频”查询实际上并没有工作。

重要的是要注意,运行此脚本时此数据库不是空的,在此之前运行了 2 个其他类似的种子文件,因此至少有 2 个视频、2 个镜头等已存储在数据库中。如果有人知道如何在不必提供静态 ID 作为外键值的情况下完成这项工作,那将为我节省大量时间。

谢谢!

最佳答案

看起来您希望 UPDATE(“主查询”)找到插入到同一 SQL 语句中的行,该行在语句开头不存在。

如果是这种情况,这将无法像 Data-Modifying Statements in WITH 中记录的那样工作:

The sub-statements in WITH are executed concurrently with each other and with the main query. Therefore, when using data-modifying statements in WITH, the order in which the specified updates actually happen is unpredictable. All the statements are executed with the same snapshot (see Chapter 13), so they cannot "see" each others' effects on the target tables. This alleviates the effects of the unpredictability of the actual order of row updates, and means that RETURNING data is the only way to communicate changes between different WITH sub-statements and the main query

您可能想使用 DO block而不是在 pl/pgsql 中以过程形式布置的几个查询。

关于postgresql - 在 WITH 子句中链接 sql 查询以最终执行更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27046330/

相关文章:

javascript - 未在 html 中定义的函数

Django + PostgreSQL 触发器导致 "violates foreign key constraint"

python - 无法使用 psycopg2 连接到 Postgres 容器

testing - 质量中心 : link to attachment

sql - 简化 WHERE (NOT) IN (...) 和 WHERE (NOT) IN (...)

postgresql - 无法加载驱动程序 org.postgresql 的模块

android - 仪器测试 - setContentView() 上的空指针异常

perl - 使用 Test::WWW::Selenium 或其他方式检测操作系统对话框

SQL - 使用一个 CTE 到另一个 CTE 的引用

java - 如何在 jOOQ 中的另一个 CTE 中重用一个 CTE