diff --git a/mkdocs/docs/configuration.md b/mkdocs/docs/configuration.md index 54d33dd00e..852142aa1f 100644 --- a/mkdocs/docs/configuration.md +++ b/mkdocs/docs/configuration.md @@ -746,12 +746,12 @@ catalog: | Key | Example | Description | |------------------------------| ------- | ------------------------------------ | -| hive.hive2-compatible | true | Using Hive 2.x compatibility mode | +| hive.hive2-compatible | true | Set to `true` when using a Hive 2.x metastore | | hive.kerberos-authentication | true | Using authentication via Kerberos | | hive.kerberos-service-name | hive | Kerberos service name (default hive) | | ugi | t-1234:secret | Hadoop UGI for Hive client. | -When using Hive 2.x, make sure to set the compatibility flag: +Hive 3 and newer need no extra configuration. When using a Hive 2.x metastore, set the compatibility flag: ```yaml catalog: diff --git a/pyiceberg/catalog/hive.py b/pyiceberg/catalog/hive.py index 94213c8332..a6dcd8196e 100644 --- a/pyiceberg/catalog/hive.py +++ b/pyiceberg/catalog/hive.py @@ -30,6 +30,7 @@ from hive_metastore.ttypes import ( AlreadyExistsException, CheckLockRequest, + DataOperationType, EnvironmentContext, FieldSchema, GetTableRequest, @@ -383,7 +384,7 @@ def _create_hive_table(self, open_client: Client, hive_table: HiveTable) -> None raise TableAlreadyExistsError(f"Table {hive_table.dbName}.{hive_table.tableName} already exists") from e def _fetch_hive_table(self, open_client: Client, database_name: str, table_name: str) -> HiveTable: - # Hive 4.0.1 removed get_table, and Hive 2 does not have get_table_req + # Hive 4.0.1 removed get_table, and Hive 2.2 and older do not have get_table_req if self._hive2_compatible: return open_client.get_table(dbname=database_name, tbl_name=table_name) return open_client.get_table_req(GetTableRequest(dbName=database_name, tblName=table_name)).table @@ -506,8 +507,16 @@ def load_view(self, identifier: str | Identifier) -> View: raise NotImplementedError def _create_lock_request(self, database_name: str, table_name: str) -> LockRequest: + # Iceberg commits are not executed within a Hive transaction, so the lock component uses operationType=NO_TXN. + # Setting it explicitly also matters for Hive 2.1, which rejects a lock component left at the default UNSET + # operation type. lock_component: LockComponent = LockComponent( - level=LockLevel.TABLE, type=LockType.EXCLUSIVE, dbname=database_name, tablename=table_name, isTransactional=True + level=LockLevel.TABLE, + type=LockType.EXCLUSIVE, + dbname=database_name, + tablename=table_name, + operationType=DataOperationType.NO_TXN, + isTransactional=True, ) lock_request: LockRequest = LockRequest(component=[lock_component], user=getpass.getuser(), hostname=socket.gethostname())