Tous les produits
Search
Centre de documentation

MaxCompute:Custom storage handler

Dernière mise à jour :Aug 10, 2026

Lorsque vos données dans OSS utilisent un format que les gestionnaires intégrés de MaxCompute ne prennent pas en charge, comme un format binaire propriétaire, un délimiteur personnalisé ou un encodage spécifique à un domaine, un gestionnaire de stockage personnalisé vous permet d'implémenter vous-même la logique de lecture et d'écriture. Vous implémentez le gestionnaire sous la forme d'une fonction définie par l'utilisateur (UDF) MaxCompute en Java, vous l'emballerez dans un fichier JAR et vous y ferez référence lors de la création de la table externe. MaxCompute délègue alors toutes les opérations de lecture et d'écriture des données à votre gestionnaire.

Notes d'utilisation

Contrainte Détail
Propriété cluster Non prise en charge sur les tables externes OSS.
Taille d'un fichier unique Ne doit pas dépasser 2 Go. Scindez les fichiers supérieurs à 2 Go avant de les référencer.
Fragmentation des données Désactivée par défaut pour éviter les problèmes d'intégrité. Activez-la uniquement si votre gestionnaire de stockage prend explicitement en charge la fragmentation.

Pour activer la fragmentation et démarrer plusieurs mappeurs, exécutez :

SET odps.sql.unstructured.data.single.file.split.enabled=true;

Créer une table externe

Syntaxe

CREATE EXTERNAL TABLE [IF NOT EXISTS] <table_name>
(
  col_name data_type,
  ...
)
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type, ...)]
STORED BY '<storage_handler_class>'
WITH SERDEPROPERTIES (
  ['property_name'='property_value', ...]
)
LOCATION 'oss://<endpoint>/<bucket>/<path>/'
USING '<jar_name>';

Pour les paramètres courants tels que les définitions de colonnes et la syntaxe de partitionnement, consultez les Paramètres de syntaxe de base.

Paramètres

Paramètre Obligatoire description
storage_handler_class Oui Nom de classe qualifié complet de votre gestionnaire de stockage personnalisé, implémenté en tant qu'UDF MaxCompute. Consultez Développer des UDF.
jar_name Oui Package JAR contenant le code du gestionnaire de stockage. Ajoutez le JAR en tant que ressource à votre projet MaxCompute avant de créer la table. Consultez Opérations sur les ressources.
resource_name Non Packages JAR supplémentaires requis lorsque votre gestionnaire utilise une classe SerDe personnalisée. Ajoutez chaque JAR en tant que ressource distincte au projet MaxCompute. Consultez Opérations sur les ressources.

Écrire des données

Pour la syntaxe d'écriture des données, consultez Écrire des données dans OSS.

Interrogation et analyse

Pour la syntaxe SELECT, consultez Lire les données OSS. Pour optimiser les plans de requête, consultez Optimisation des requêtes.

Exemple : Créer une table externe OSS à l'aide d'un gestionnaire de stockage personnalisé

Cet exemple mappe une table externe MaxCompute au répertoire SampleData/ dans OSS à l'aide d'un gestionnaire de stockage personnalisé basé sur du texte. Le gestionnaire lit les lignes délimitées par des barres verticales (|) depuis les objets OSS et les mappe vers des colonnes typées.

Prérequis

Avant de commencer, assurez-vous que vous disposez des éléments suivants :

Procédure

  1. Utilisez MaxCompute Studio pour créer les quatre classes Java suivantes. Les liens pointent vers des implémentations de référence dans le SDK Java d'Alibaba Cloud :

    Pour obtenir des conseils sur le développement d'UDF Java, consultez Développer une UDF.

  2. Utilisez la fonctionnalité d'emballage en un clic de MaxCompute Studio pour empaqueter TextStorageHandler.java et le télécharger en tant que ressource MaxCompute. Cet exemple suppose que la ressource est nommée javatest-1.0-SNAPSHOT.jar. Pour les étapes d'emballage et de téléchargement, consultez Empaqueter, télécharger et enregistrer.

    Si votre gestionnaire de stockage possède plusieurs dépendances, emballez chacune d'elles séparément et téléchargez-les en tant que ressources MaxCompute individuelles.
  3. Créez la table externe :

    CREATE EXTERNAL TABLE ambulance_data_txt_external
    (
      vehicleId INT,
      recordId INT,
      patientId INT,
      calls INT,
      locationLatitute DOUBLE,
      locationLongtitue DOUBLE,
      recordTime STRING,
      direction STRING
    )
    STORED BY 'com.aliyun.odps.udf.example.text.TextStorageHandler'
    WITH SERDEPROPERTIES (
      'delimiter'='|',
      'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
    )
    LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/SampleData/'
    USING 'javatest-1.0-SNAPSHOT.jar';

    La propriété delimiter définit le séparateur de colonnes utilisé dans chaque ligne des objets OSS. Toute chaîne valide est acceptée.

    Pour vérifier la structure de la table après sa création, exécutez :

    DESC EXTENDED ambulance_data_txt_external;
  4. Lisez les données de la table :

    SELECT recordId, patientId, direction FROM ambulance_data_txt_external WHERE patientId > 25;

    Résultat attendu :

    +----------+-----------+-----------+
    | recordid | patientid | direction |
    +----------+-----------+-----------+
    | 1        | 51        | S         |
    | 3        | 48        | NE        |
    | 4        | 30        | W         |
    | 5        | 47        | S         |
    | 7        | 53        | N         |
    | 8        | 63        | SW        |
    | 10       | 31        | N         |
    +----------+-----------+-----------+
  5. Écrivez des données dans la table :

    INSERT INTO ambulance_data_txt_external VALUES (1,16,76,1,'46.81006','-92.08174','9/14/2014 0:10','SW');

    Pour vérifier l'écriture, interrogez la ligne que vous avez insérée ou vérifiez la présence d'un nouveau fichier dans le répertoire OSS :

    SELECT * FROM ambulance_data_txt_external WHERE recordId='16';

FAQ

Pourquoi l'erreur ODPS-0123131 se produit-elle lors de la lecture d'un champ DATETIME à l'aide d'un Extractor personnalisé ?

La cause racine est java.sql.Date.valueOf(), qui n'accepte que les chaînes au format "yyyy-[m]m-[d]d". Lorsque la valeur du champ inclut une composante horaire (par exemple, 2019-11-11 06:43:36), l'appel échoue avec une IllegalArgumentException.

Corrigez ce problème en ajoutant la bibliothèque Joda-Time et en utilisant DateTimeFormat.forPattern() pour analyser la valeur :

  1. Ajoutez la dépendance Joda-Time à votre projet :

    <dependency>
      <groupId>joda-time</groupId>
      <artifactId>joda-time</artifactId>
      <version>2.10</version>
    </dependency>
  2. Importez les classes requises :

    import org.joda.time.DateTime;
    import org.joda.time.format.DateTimeFormat;
  3. Remplacez l'appel à Date.valueOf() par une analyse Joda-Time :

    record.setDate(index, new Date(DateTime.parse(parts[i], DateTimeFormat.forPattern("yyyy-MM-dd HH:mi:ss")).getMillis()));
  4. Téléchargez le JAR Extractor mis à jour et le JAR Joda-Time en tant que ressources MaxCompute :

    ADD JAR /path/to/text_extractor-1.0-SNAPSHOT.jar;
    ADD JAR /path/to/joda-time-2.10.jar;
  5. Téléchargez un fichier de test vers OSS. Format de ligne d'exemple :

    5c661071dba64d5080c91da085ff1073^music-click-fast_forward^26.12.XX.XX^2019-11-11 06:43:36
  6. Interrogez la table externe pour confirmer l'analyse réussie :

    SELECT * FROM <project_name>.video_play_log;

    Résultat attendu :

    +----------------------------------+--------------------------+-------------+---------------------+
    | uuid                             | action                   | ip          | time                |
    +----------------------------------+--------------------------+-------------+---------------------+
    | 5c661071dba64d5080c91da085ff1073 | music-click-fast_forward | 26.12.XX.XX | 2019-11-11 06:43:36 |
    +----------------------------------+--------------------------+-------------+---------------------+