2012-06-29 11 views
18

he definido una tabla como tal:Al crear una tabla externa en la colmena, ¿puedo señalar la ubicación a archivos específicos en un directorio?

create external table PageViews (Userid string, Page_View string) 
partitioned by (ds string) 
row format as delimited fields terminated by ',' 
stored as textfile location '/user/data'; 

no quiero todos los archivos en el directorio/user/datos a utilizar como parte de la mesa. ¿Es posible para mí hacer lo siguiente?

location 'user/data/*.csv' 

Respuesta

8

Encontré este hilo cuando tuve un problema similar para resolver. Pude resolverlo usando un SerDe personalizado. Luego agregué propiedades SerDe que guiaban qué RegEx aplicar a los patrones de nombre de archivo para cualquier tabla en particular.

Un SerDe personalizado puede parecer excesivo si solo se trata de archivos CSV estándar, tenía un formato de archivo más complejo para tratar. Aún así, esta es una solución muy viable si no teme escribir algo de Java. Es particularmente útil cuando no puede reestructurar los datos en su ubicación de almacenamiento y está buscando un patrón de archivo muy específico entre un conjunto de archivos desproporcionadamente grande.

> CREATE EXTERNAL TABLE PageViews (Userid string, Page_View string) 
> ROW FORMAT SERDE 'com.something.MySimpleSerDe' 
> WITH SERDEPROPERTIES ("input.regex" = "*.csv") 
> LOCATION '/user/data'; 
+0

no funciona con opencsvserde – thebluephantom

6

No, actualmente no puede hacer eso. Hay un boleto JIRA abierto para permitir la selección de expresiones regulares de los archivos incluidos para las tablas de Hive (https://issues.apache.org/jira/browse/HIVE-951).

Por ahora su mejor opción es crear una tabla en un directorio diferente y simplemente copiar en los archivos que desea consultar.

+1

Veo que este problema aún está abierto ... – Haimei

15

Lo que kmosley dijo es verdad. A partir de ahora, no puede seleccionar selectivamente ciertos archivos para que formen parte de su tabla Hive. Sin embargo, hay dos formas de evitarlo.

Opción 1: puede mover todos los archivos CSV en otro directorio HDFS y crear una mesa Colmena por encima de eso. Si funciona mejor para usted, puede crear un subdirectorio (por ejemplo, csv) dentro de su directorio actual que contenga todos los archivos CSV. A continuación, puede crear una tabla Hive en la parte superior de este subdirectorio. Tenga en cuenta que las tablas de Hive creadas en la parte superior del directorio principal NO contendrán los datos del subdirectorio.

Opción 2: Usted puede cambiar sus consultas a hacer uso de una columna virtual llamado INPUT__FILE__NAME.

Su consulta sería algo como:

SELECT 
    * 
FROM 
    my_table 
WHERE 
    INPUT__FILE__NAME LIKE '%csv'; 

El mal efecto de este enfoque es que la consulta Colmena tendrá que batir a través de los datos completos presentes en el directorio a pesar de que sólo se preocupaba por archivos específicos. La consulta no filtrará los archivos basados ​​en el predicado usando INPUT__FILE__NAME. Simplemente filtrará los registros que no provienen de la coincidencia del predicado usando INPUT__FILE__NAME durante la fase del mapa (en consecuencia filtrando todos los registros de archivos particulares), pero los correlacionadores también se ejecutarán en archivos innecesarios. Le dará el resultado correcto, podría tener una sobrecarga de rendimiento, probablemente menor.

El beneficio de este enfoque es que puede usar la misma tabla Hive si tiene varios archivos en la tabla y desea consultar todos los archivos de esa tabla (o su partición) en algunas consultas y un subconjunto de los archivos en otras consultas. Puede hacer uso de la columna virtual INPUT__FILE__NAME para lograr eso.A modo de ejemplo: si una partición en el directorio de HDFS /user/hive/warehouse/web_logs/ parecía:

/user/hive/warehouse/web_logs/dt=2012-06-30/ 
    /user/hive/warehouse/web_logs/dt=2012-06-30/00.log 
    /user/hive/warehouse/web_logs/dt=2012-06-30/01.log 
    . 
    . 
    . 
    /user/hive/warehouse/web_logs/dt=2012-06-30/23.log 

Digamos que su definición de la tabla parecía:

CREATE EXTERNAL TABLE IF NOT EXISTS web_logs_table (col1 STRING) 
PARTITIONED BY (dt STRING) 
LOCATION '/user/hive/warehouse/web_logs'; 

Después de añadir las particiones apropiadas, se puede consultar todos los registros en la partición utilizando una consulta como:

SELECT 
    * 
FROM 
    web_logs_table w 
WHERE 
    dt='2012-06-30'; 

Sin embargo, si sólo se preocupaba por los registros de la primera hora del día, usted podría consultar los registros de la primera hora utilizando una consulta como:

SELECT 
    * 
FROM 
    web_logs_table w 
WHERE 
    dt ='2012-06-30' 
    AND INPUT__FILE__NAME='00.log'; 

Otro caso de uso similar podría ser un directorio que contiene registros de la tela de diferentes dominios y varias consultas necesidad de analizar los registros en diferentes conjuntos de dominios. Las consultas pueden filtrar dominios mediante la columna virtual INPUT__FILE__NAME.

En los dos casos de uso anteriores, tener una subpartición por hora o dominio también resolvería el problema, sin tener que usar la columna virtual. Sin embargo, puede haber algunas concesiones de diseño que requieren que no se creen subparticiones. En ese caso, podría decirse que usar la columna virtual INPUT__FILE__NAME es su mejor apuesta.

Decidir entre las 2 opciones:

Realmente depende de su caso de uso. Si nunca le importarían los archivos que está tratando de excluir de la tabla Hive, usar la Opción 2 es probablemente una exageración y debe arreglar la estructura del directorio y crear una tabla Hive en la parte superior del directorio que contenga los archivos que le interesan. .

Si los archivos que actualmente excluye siguen el mismo formato que los otros archivos (para que todos puedan ser parte de la misma tabla Hive) y podría verse escribiendo una consulta que analizaría todos los datos en el directorio, luego vaya con la Opción 2.

+0

Gracias Mark. Actualmente estoy haciendo la Opción 1 en producción, pero probaré la Opción 2 en mi entorno Dev para poder agregarlo a mi toolbelt –

+0

para 'INPUT__FILE__NAME'. Todavía necesita escanear todos los datos, pero puede ser útil de todos modos ... especialmente cuando no quiere/tiene/no puede particionar – msciwoj

+0

La opción n. ° 2 sigue siendo un problema cuando tiene una SOBRESCRIBIR INSERTAR, eliminará todos los archivos, incluso si solo quieres sobrescribir uno de ellos. – Dhiraj

Cuestiones relacionadas