Dian Fu created FLINK-40197:
-------------------------------

             Summary: Add sql bindings to DataFrame API
                 Key: FLINK-40197
                 URL: https://issues.apache.org/jira/browse/FLINK-40197
             Project: Flink
          Issue Type: Sub-task
          Components: API / Python
            Reporter: Dian Fu
             Fix For: 2.4.0


def sql(
    query: str,
    *,
    auto_bind: bool = True,
    **bindings,
) -> DataFrame

Run a SQL SELECT query and return its result as a DataFrame, so SQL and the 
DataFrame API mix freely. DataFrames referenced in the query are exposed as 
temporary views, and @pf.udf / @pf.udtf functions as temporary functions; both 
are registered only for the duration of the call and dropped afterwards.

There are two ways to make Python objects visible to the query:

* Auto-bind (default, auto_bind=True): sql scans the caller's local and global 
variables for DataFrame and UDF/UDTF objects and registers each under its 
Python variable name. Auto-bind is best-effort — it warns and skips names that 
are not valid SQL identifiers or that collide with an existing 
table/view/function, and it never shadows permanent catalog objects or built-in 
functions.
* Explicit bindings: pass keyword arguments to choose the SQL name yourself, 
e.g. pf.sql("SELECT * FROM s", s=df). Explicit bindings are strict (conflicts 
raise ValueError), take precedence over auto-bind on name collisions, and are 
required to intentionally shadow a catalog table/view or a built-in function.

Only SELECT queries are supported (no INSERT / DDL). The returned DataFrame can 
be further transformed with the DataFrame API.

Example:

{code:python}
import pyflink.dataframe as pf

df1 = pf.from_dict({"a": [1, 2, 3], "b": ["x", "y", "z"]})
df2 = pf.from_dict({"a": [1, 2, 3], "c": ["p", "q", "r"]})

# Auto-bind: df1 / df2 are registered under their variable names
joined = pf.sql("SELECT df1.a, b, c FROM df1 JOIN df2 ON df1.a = df2.a")

# UDFs are auto-bound too
@pf.udf
def add_one(x: int) -> int:
    return x + 1

incremented = pf.sql("SELECT add_one(a) AS a1 FROM df1")

# Explicit bindings: pick the SQL names, turn off scanning
result = pf.sql(
    "SELECT * FROM src WHERE a > 1",
    auto_bind=False,
    src=df1,
)

# Mix SQL and the DataFrame API
pf.sql("SELECT a, b FROM df1").filter(pf.col("a") > 1).to_pandas()
{code}




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to