Hive获取Flink CatalogBaseTable中的类型获取和转换

文章详细介绍了Hive的FieldSchema核心属性,包括字段名、类型和注释。在HiveCatalog中,通过getTable方法获取表信息,然后利用HiveTableUtil将Hive的表结构转化为Flink的CatalogBaseTable。关键步骤是将Hive的字符串类型转化为Flink的DataType,这个过程涉及到HiveTypeUtil的toFlinkType方法,将Hive的PRIMITIVE、LIST、MAP和STRUCT等数据类型转换为Flink对应的数据类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hive FieldSchema的核心属性。

public class FieldSchema {
  private String name; // required
  private String type; // required
  private String comment; // required
}

HiveCatalog获取

    public CatalogBaseTable getTable(ObjectPath tablePath)
            throws TableNotExistException, CatalogException {
        checkNotNull(tablePath, "tablePath cannot be null");
// 获取hiveTable 此Table中字段类型是字符串存储的。
        Table hiveTable = getHiveTable(tablePath);
        return instantiateCatalogTable(hiveTable, hiveConf);
    }

instantiateCatalogTable 将HiveTable转化为Flink CatalogBaseTable

private CatalogBaseTable instantiateCatalogTable(Table hiveTable, HiveConf hiveConf) {
            List<FieldSchema> fields = getNonPartitionFields(hiveConf, hiveTable);
            tableSchema =
                    HiveTableUtil.createTableSchema(
                            fields,
                            hiveTable.getPartitionKeys(),
                            notNullColumns,
                            primaryKey.orElse(null));
}

HiveTableUtil

    public static TableSchema createTableSchema(
            List<FieldSchema> cols,
            List<FieldSchema> partitionKeys,
            Set<String> notNullColumns,
            UniqueConstraint primaryKey) {
        List<FieldSchema> allCols = new ArrayList<>(cols);
        allCols.addAll(partitionKeys);

        String[] colNames = new String[allCols.size()];
        DataType[] colTypes = new DataType[allCols.size()];

        for (int i = 0; i < allCols.size(); i++) {
            FieldSchema fs = allCols.get(i);

            colNames[i] = fs.getName();
            // 核心代码 将字符串的类型如"varchar(20)" 转化为DataTypes.VARCHAR(20);
            colTypes[i] = HiveTypeUtil.toFlinkType(TypeInfoUtils.getTypeInfoFromTypeString(fs.getType()));
            if (notNullColumns.contains(colNames[i])) {
                colTypes[i] = colTypes[i].notNull();
            }
        }
        TableSchema.Builder builder = TableSchema.builder().fields(colNames, colTypes);
        if (primaryKey != null) {
            builder.primaryKey(
                    primaryKey.getName(), primaryKey.getColumns().toArray(new String[0]));
        }
        return builder.build();
    }

toFlinkType是将String的类型名称实际转化为DataType的工具。

    /**
     * Convert Hive data type to a Flink data type.
     *
     * @param hiveType a Hive data type
     * @return the corresponding Flink data type
     */
    public static DataType toFlinkType(TypeInfo hiveType) {
        checkNotNull(hiveType, "hiveType cannot be null");

        switch (hiveType.getCategory()) {
            case PRIMITIVE:
                return toFlinkPrimitiveType((PrimitiveTypeInfo) hiveType);
            case LIST:
                ListTypeInfo listTypeInfo = (ListTypeInfo) hiveType;
                return DataTypes.ARRAY(toFlinkType(listTypeInfo.getListElementTypeInfo()));
            case MAP:
                MapTypeInfo mapTypeInfo = (MapTypeInfo) hiveType;
                return DataTypes.MAP(
                        toFlinkType(mapTypeInfo.getMapKeyTypeInfo()),
                        toFlinkType(mapTypeInfo.getMapValueTypeInfo()));
            case STRUCT:
                StructTypeInfo structTypeInfo = (StructTypeInfo) hiveType;

                List<String> names = structTypeInfo.getAllStructFieldNames();
                List<TypeInfo> typeInfos = structTypeInfo.getAllStructFieldTypeInfos();

                DataTypes.Field[] fields = new DataTypes.Field[names.size()];

                for (int i = 0; i < fields.length; i++) {
                    fields[i] = DataTypes.FIELD(names.get(i), toFlinkType(typeInfos.get(i)));
                }

                return DataTypes.ROW(fields);
            default:
                throw new UnsupportedOperationException(
                        String.format("Flink doesn't support Hive data type %s yet.", hiveType));
        }
    }

toFlinkPrimitiveType
简单看一下就是switch ,且并没有对DataType进行bridegeTo操作。使用的是默认内置类型。


    private static DataType toFlinkPrimitiveType(PrimitiveTypeInfo hiveType) {
        checkNotNull(hiveType, "hiveType cannot be null");

        switch (hiveType.getPrimitiveCategory()) {
            case CHAR:
                return DataTypes.CHAR(((CharTypeInfo) hiveType).getLength());
            case VARCHAR:
                return DataTypes.VARCHAR(((VarcharTypeInfo) hiveType).getLength());
            case STRING:
                return DataTypes.STRING();
            case BOOLEAN:
                return DataTypes.BOOLEAN();
            case BYTE:
                return DataTypes.TINYINT();
            case SHORT:
                return DataTypes.SMALLINT();
            case INT:
                return DataTypes.INT();
            case LONG:
                return DataTypes.BIGINT();
            case FLOAT:
                return DataTypes.FLOAT();
            case DOUBLE:
                return DataTypes.DOUBLE();
            case DATE:
                return DataTypes.DATE();
            case TIMESTAMP:
                return DataTypes.TIMESTAMP(9);
            case BINARY:
                return DataTypes.BYTES();
            case DECIMAL:
                DecimalTypeInfo decimalTypeInfo = (DecimalTypeInfo) hiveType;
                return DataTypes.DECIMAL(
                        decimalTypeInfo.getPrecision(), decimalTypeInfo.getScale());
            default:
                throw new UnsupportedOperationException(
                        String.format(
                                "Flink doesn't support Hive primitive type %s yet", hiveType));
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值