使用python的trino包执行insert overwrite,但是overwrite却没有生效的问题
根据trino的官网介绍的insert overwrite的开启方式,开启hive的insert overwrite会话,使当前会话的insert into语句支持insert overwrite,也即支持插入数据根据分区覆盖更新的功能
但是在使用Python代码执行时总是没有生效,在花了不少时间debug之后,终于找到了原因竟是因为开启insert overwrite session的语句没有执行fetchall()而导致没有生效
下面是执行的的代码示例
import trino  def insert_overwrite_query(trino, ...):     conn = trino.dbapi.connect()     cursor: Cursor = conn.cursor()     overwrite_sql = "SET SESSION hive.insert_existing_partitions_behavior = 'OVERWRITE'"     cursor.execute(overwrite_sql)     query = """insert into hive.schema.table ..."""     cursor.execute(query)    	res = cursor.fetchall()    	... overwrite_sql在执行之后需要执行cursor.fetchall()才会生效,在此之前实在不明白这条sql为什么需要fetchall()?fetchall()的作用不是在需要返回数据时才执行吗?
在一番搜寻之后才了解到fetchall()的真正运作机制
另外就是python trino中的fetchall()的作用了,一番源码观察之后,确定了trino的查询机制
根据cursor.fetchall() 找到了其数据实际上来自于一个生成器对象TrinoResult,在fetchall()的时候实际上执行了list(TrinoResult(...))取得了查询结果(实际上你执行list(cursor.execute(query))也会得到fetchall()相同的结果)
class TrinoResult(object):     def __init__(self, query, rows=None, experimental_python_types: bool = False):         self._query = query         self._rows = rows or []         self._rownumber = 0         self._experimental_python_types = experimental_python_types 	 	... 	     def __iter__(self):         # Initial fetch from the first POST request         for row in self._rows:             self._rownumber += 1             yield row         self._rows = None          # Subsequent fetches from GET requests until next_uri is empty.         while not self._query.finished:             rows = self._query.fetch()             for row in rows:                 self._rownumber += 1                 logger.debug("row %s", row)                 if not self._experimental_python_types:                     yield row                 else:                     yield self._map_to_python_types(row, self._query.columns) 总之,在session sql后面需要在执行一次fetchall()才会使开启session的sql生效,但是总觉得有点不符合直觉