Se você está realizando alguma ingestão via streaming, utilizando spark, é possível que algum dia tenha pesquisado no google por spark streaming foreachBatch createOrReplaceTempView, e é quase certo que encontrou esse resultado aqui:

from pyspark import Row
  
# Function to upsert `microBatchOutputDF` into Delta table using MERGE
def upsertToDelta(microBatchOutputDF, batchId): 
    # Set the dataframe to view updates
    microBatchOutputDF.createOrReplaceTempView("updates")

    # Use the view updates to apply MERGE
    # NOTE: You have to use the SparkSession that has been used to define the 
    # `updates` dataframe
    microBatchOutputDF._jdf.sparkSession().sql("""
    MERGE INTO aggregates t
    USING updates s
    ON s.key = t.key
    WHEN MATCHED THEN UPDATE SET *
    WHEN NOT MATCHED THEN INSERT *
    """)

De certa forma, isso soluciona o problema, mas não é algo tão elegante. Apesar do próprio notebook da documentação da Databricks indicar esta utilização do .jdf_sparkSession() como uma solução viável, fica meio vago o porque precisamos utilizar, e também não é idiomático/recomendado a utilização de métodos iniciados por um _ underscore, visto que são métodos considerados privados.

Se pesquisarmos na documentação do PySpark, não encontramos um atributo chamado _jdf. Até encontramos o sql_ctx, mas esse foi descontinuado por causa da criação de um novo atributo chamado sparkSession, que nos retorna a SparkSession que criou o dataframe.

Resumo da Ópera

O time do Spark, na JIRA SPARK-38121 realizou uma melhoria que disponibiliza esse atributo sparkSession, o que muda o código acima para algo mais simples, conciso e elegante:

from pyspark import Row
  
def upsertToDelta(microBatchOutputDF, batchId): 
    microBatchOutputDF.createOrReplaceTempView("updates")

    microBatchOutputDF.sparkSession.sql("""
    MERGE INTO aggregates t
    USING updates s
    ON s.key = t.key
    WHEN MATCHED THEN UPDATE SET *
    WHEN NOT MATCHED THEN INSERT *
    """)

Dessa maneira não é preciso tratar o código para utilizar algum atributo privado ou utilizar o contexto sql com a criação de views globais.

Referências e leituras adicionais

Spark Session and the singleton misconception
Spark: Why should we use SparkSession ?
A tale of Spark Session and Spark Context