コード例 #1
0
def test_cte_in_source():
    cte = select(source.c.s1).cte("cte")
    sub = select(cte.c.s1).select_from(cte).subquery()

    query = MergeInto(target=target,
                      source=sub,
                      onclause=target.c.t1 == sub.c.s1,
                      when_clauses=[
                          WhenMatched(
                              update(target).values({target.c.t1: sub.c.s1})),
                      ])

    expected = """\
        MERGE INTO `target`
        USING (WITH `cte` AS 
        (SELECT `source`.`s1` AS `s1` 
        FROM `source`)
         SELECT `cte`.`s1` AS `s1` 
        FROM `cte`) AS `anon_1`
        ON `target`.`t1` = `anon_1`.`s1`
        WHEN MATCHED THEN 
        \tUPDATE  SET `t1`=`anon_1`.`s1`
        """

    assert str(query.compile(dialect=BigQueryDialect())) == dedent(expected)
コード例 #2
0
def test_example_2():
    expected = """\
        MERGE INTO dataset.Inventory AS T
        USING dataset.NewArrivals AS S
        ON T.product = S.product
        WHEN MATCHED THEN 
            UPDATE  SET quantity=(T.quantity + S.quantity)
        WHEN NOT MATCHED BY TARGET THEN 
            INSERT (product, quantity) VALUES (S.product, S.quantity)
        """

    T = inventory.alias("T")
    S = new_arrivals.alias("S")

    query = MergeInto(target=T,
                      source=S,
                      onclause=T.c.product == S.c.product,
                      when_clauses=[
                          WhenMatched(
                              update(T).values({
                                  T.c.quantity:
                                  T.c.quantity + S.c.quantity,
                              }), ),
                          WhenNotMatched(
                              insert(T).values({
                                  T.c.product: S.c.product,
                                  T.c.quantity: S.c.quantity,
                              }), )
                      ])

    return query, expected
コード例 #3
0
def test_example_6():
    expected = """\
        MERGE INTO dataset.Inventory AS T
        USING (SELECT t1.product AS product, t1.quantity AS quantity, t2.state AS state FROM dataset.NewArrivals AS t1 JOIN dataset.Warehouse AS t2 ON t1.warehouse = t2.warehouse) AS S
        ON T.product = S.product
        WHEN MATCHED AND S.state = 'CA' THEN 
            UPDATE SET quantity=(T.quantity + S.quantity)
        WHEN MATCHED THEN 
            DELETE
        """

    T = inventory.alias("T")
    NA = new_arrivals.alias("t1")
    W = warehouse.alias("t2")
    S = select(NA.c.product, NA.c.quantity, W.c.state).select_from(
        join(NA, W, NA.c.warehouse == W.c.warehouse)).alias("S")

    query = MergeInto(target=T,
                      source=S,
                      onclause=T.c.product == S.c.product,
                      when_clauses=[
                          WhenMatched(update(T).values({
                              T.c.quantity:
                              T.c.quantity + S.c.quantity,
                          }),
                                      condition=S.c.state == "CA"),
                          WhenMatched(delete(T))
                      ])

    return query, expected
コード例 #4
0
def test_example_8():
    expected = """\
        MERGE INTO dataset.NewArrivals
        USING (SELECT * FROM unnest([('microwave', 10, 'warehouse #1'), ('dryer', 30, 'warehouse #1'), ('oven', 20, 'warehouse #2')])) AS anon_1
        ON false
        WHEN NOT MATCHED BY TARGET THEN
          INSERT ROW
        WHEN NOT MATCHED BY SOURCE THEN
          DELETE
        """

    values = [
        str(("microwave", 10, "warehouse #1")),
        str(("dryer", 30, "warehouse #1")),
        str(("oven", 20, "warehouse #2")),
    ]
    values = ", ".join(values)

    T = new_arrivals
    S = select("*").select_from(func.UNNEST(text(f"[{values}]"))).subquery(
    )  # can't get `func.UNNEST(values)` to work, renders as `UNNEST(NULL)`?

    query = MergeInto(target=T,
                      source=S,
                      onclause=literal(False),
                      when_clauses=[
                          WhenNotMatched(insert(T)),
                          WhenNotMatchedBySource(delete(T))
                      ])

    return query, expected
コード例 #5
0
def test_example_3():
    expected = """\
        MERGE INTO dataset.NewArrivals AS T
        USING (SELECT dataset.NewArrivals.product AS product FROM dataset.NewArrivals WHERE dataset.NewArrivals.warehouse != 'warehouse #2') AS S
        ON T.product = S.product
        WHEN MATCHED AND T.warehouse = 'warehouse #1' THEN 
            UPDATE  SET quantity=(T.quantity + 20)
        WHEN MATCHED THEN 
            DELETE
        """

    T = new_arrivals.alias("T")
    S = select(new_arrivals.c.product).where(
        new_arrivals.c.warehouse != "warehouse #2").alias("S")

    query = MergeInto(target=T,
                      source=S,
                      onclause=T.c.product == S.c.product,
                      when_clauses=[
                          WhenMatched(
                              update(T).values({
                                  T.c.quantity: T.c.quantity + 20,
                              }),
                              condition=T.c.warehouse == "warehouse #1"),
                          WhenMatched(delete(T))
                      ])

    return query, expected
コード例 #6
0
def test_conditions(connection, target, source):
    query = MergeInto(
        target=target,
        source=source,
        onclause=target.c.t1 == source.c.s1,
        when_clauses=[
            WhenNotMatchedBySource(delete(target), condition=target.c.t2 > date.today()),
        ]
    )

    connection.execute(query)
コード例 #7
0
def test_constant_onclause(connection, target, source):
    query = MergeInto(
        target=target,
        source=source,
        onclause=literal(False),
        when_clauses=[
            WhenNotMatchedBySource(delete(target)),
        ]
    )

    connection.execute(query)
コード例 #8
0
def test_when_not_matched_by_source(connection, target, source):
    query = MergeInto(
        target=target,
        source=source,
        onclause=target.c.t1 == source.c.s1,
        when_clauses=[
            WhenNotMatchedBySource(delete(target)),
        ]
    )

    connection.execute(query)
コード例 #9
0
def test_brackets_in_actions():
    query = MergeInto(target=target,
                      source=source,
                      onclause=target.c.t1 == source.c.s1,
                      when_clauses=[
                          WhenMatched(
                              update(target).values({target.c.t1: "{}"})),
                      ])

    expected = """\
        MERGE INTO `target`
        USING `source`
        ON `target`.`t1` = `source`.`s1`
        WHEN MATCHED THEN 
        \tUPDATE  SET `t1`='{}'
        """

    assert str(
        query.compile(dialect=BigQueryDialect(),
                      compile_kwargs={'literal_binds':
                                      True})) == dedent(expected)
コード例 #10
0
def test_when_not_matched():
    query = MergeInto(target=target,
                      source=source,
                      onclause=target.c.t1 == source.c.s1,
                      when_clauses=[
                          WhenNotMatched(
                              insert(target).values({
                                  target.c.t2:
                                  source.c.s2 + timedelta(days=1).days
                              })),
                      ])

    expected = """\
        MERGE INTO `target`
        USING `source`
        ON `target`.`t1` = `source`.`s1`
        WHEN NOT MATCHED BY TARGET THEN 
        \tINSERT (`t2`) VALUES ((`source`.`s2` + :s2_1))
        """

    assert str(query.compile(dialect=BigQueryDialect())) == dedent(expected)
コード例 #11
0
def test_when_not_matched(connection, target, source):
    query = MergeInto(
        target=target,
        source=source,
        onclause=target.c.t1 == source.c.s1,
        when_clauses=[
            WhenNotMatched(insert(target).values({
                target.c.t2: source.c.s2 + timedelta(days=1).days
            })),
        ]
    )

    connection.execute(query)
コード例 #12
0
def test_parameterless_insert(connection, target, source):
    query = MergeInto(
        target=target,
        source=source,
        onclause=target.c.t1 == source.c.s1,
        when_clauses=[
            WhenNotMatched(insert(target), condition=source.c.s1 != None),
            WhenNotMatched(insert(target).values(t1="dummy"), condition=source.c.s2 < date.today()),
            WhenNotMatched(insert(target)),
        ]
    )

    connection.execute(query)
コード例 #13
0
def test_alias_on_source(connection, target, source):
    alias = source.alias("alias_s")
    query = MergeInto(
        target=target,
        source=alias,
        onclause=target.c.t1 == alias.c.s1,
        when_clauses=[
            WhenNotMatchedBySource(delete(target)),
            WhenNotMatched(insert(target).values(t1=alias.c.s1)),
            WhenMatched(update(target).values(t2=alias.c.s2)),
        ]
    )

    connection.execute(query)
コード例 #14
0
def test_alias_on_target(connection, target, source):
    alias = target.alias("alias_t")
    query = MergeInto(
        target=alias,
        source=source,
        onclause=alias.c.t1 == source.c.s1,
        when_clauses=[
            WhenNotMatchedBySource(delete(alias), condition=alias.c.t2 > date.today()),
            WhenNotMatched(insert(alias).values(t1="dummy")),
            WhenMatched(update(alias).values(t2=date.today())),
        ]
    )

    connection.execute(query)
コード例 #15
0
def test_multiple_when_clauses(connection, target, source):
    query = MergeInto(
        target=target,
        source=source,
        onclause=target.c.t1 == source.c.s1,
        when_clauses=[
            WhenMatched(update(target).values({
                target.c.t2: source.c.s2 + timedelta(days=1).days
            })),
            WhenNotMatchedBySource(delete(target), condition=target.c.t2 > date.today()),
        ]
    )

    connection.execute(query)
コード例 #16
0
def test_when_matched():
    query = MergeInto(target=target,
                      source=source,
                      onclause=target.c.t1 == source.c.s1,
                      when_clauses=[
                          WhenMatched(
                              update(target).values({
                                  target.c.t2:
                                  source.c.s2 + timedelta(days=1).days
                              }))
                      ])

    # sneaky double space in the last line (between UPDATE & SET)
    # due to how the UPDATE clause is transformed (direct string manipulation)
    expected = """\
        MERGE INTO `target`
        USING `source`
        ON `target`.`t1` = `source`.`s1`
        WHEN MATCHED THEN 
        \tUPDATE  SET `t2`=(`source`.`s2` + :s2_1)
        """

    assert str(query.compile(dialect=BigQueryDialect())) == dedent(expected)
コード例 #17
0
def test_update_shared_columns(connection, target, source):
    sub = select(source.c.s1.label("t1")).alias("sub")

    query = MergeInto(
        target=target,
        source=sub,
        onclause=target.c.t1 == sub.c.t1,
        when_clauses=[
            WhenMatched(update(target).values({
                target.c.t1: sub.c.t1
            })),
        ]
    )

    connection.execute(query)
コード例 #18
0
def test_subquery_in_source(connection, target, source):
    sub = select((source.c.s1 + "_sub").label("s3")).alias("sub")

    query = MergeInto(
        target=target,
        source=sub,
        onclause=target.c.t1 == sub.c.s3,
        when_clauses=[
            WhenMatched(update(target).values({
                target.c.t1: sub.c.s3
            })),
            WhenNotMatchedBySource(delete(target)),
        ]
    )

    connection.execute(query)
コード例 #19
0
def test_cte_in_source(connection, target, source):
    cte = select(source.c.s1).cte("cte")
    sub = select(cte.c.s1).select_from(cte).subquery()

    query = MergeInto(
        target=target,
        source=sub,
        onclause=target.c.t1 == sub.c.s1,
        when_clauses=[
            WhenMatched(update(target).values({
                target.c.t1: sub.c.s1
            })),
        ]
    )

    connection.execute(query)
コード例 #20
0
def test_example_1():
    expected = """\
        MERGE INTO dataset.DetailedInventory AS T
        USING dataset.Inventory AS S
        ON T.product = S.product
        WHEN NOT MATCHED BY TARGET AND T.quantity < 20 THEN 
            INSERT (product, quantity, supply_constrained, comments)
            VALUES (S.product, S.quantity, true, ARRAY<STRUCT<created DATE, comment STRING>>[(DATE('2016-01-01'), 'comment1')])
        WHEN NOT MATCHED BY TARGET THEN 
            INSERT (product, quantity, supply_constrained)
            VALUES (S.product, S.quantity, false)
        """

    T = detailed_inventory.alias("T")
    S = inventory.alias("S")

    # without a meaningful variable name this is more confusing than anything really,
    # but it lets me check this sort of factoring out works too.
    default_insert = insert(T).values({
        T.c.product: S.c.product,
        T.c.quantity: S.c.quantity,
        T.c.supply_constrained: literal(False),
    })

    query = MergeInto(
        target=T,
        source=S,
        onclause=T.c.product == S.c.product,
        when_clauses=[
            WhenNotMatched(
                default_insert.values({
                    T.c.supply_constrained:
                    literal(True),
                    # can't figure this one out without cheating a bit
                    T.c.comments:
                    text(
                        "ARRAY<STRUCT<created DATE, comment STRING>>[(DATE('2016-01-01'), 'comment1')]"
                    )
                }),
                condition=T.c.quantity < 20),
            WhenNotMatched(default_insert)
        ])

    return query, expected