Découvrez comment créer, lire et écrire des tables externes pour les données CSV et TSV stockées dans Object Storage Service (OSS).
Remarques d'utilisation
Les tables externes OSS ne prennent pas en charge la propriété de cluster.
La taille d'un fichier unique ne peut pas dépasser 2 Go. Vous devez fractionner les fichiers dont la taille est supérieure à 2 Go.
MaxCompute et OSS doivent se trouver dans la même région.
Types de données pris en charge
Pour plus d'informations sur les types de données MaxCompute, consultez Data Type Version 1.0 et Data Type Version 2.0.
Pour plus d'informations sur SmartParse, reportez-vous à la section Compatibilité flexible des types de Smart Parse.
Type | com.aliyun.odps.CsvStorageHandler/ TsvStorageHandler (Built-in) | org.apache.hadoop.hive.serde2.OpenCSVSerde (Open-source) |
TINYINT | ||
SMALLINT | ||
INT | ||
BIGINT | ||
BINARY | ||
FLOAT | ||
DOUBLE | ||
DECIMAL(precision,scale) | ||
VARCHAR(n) | ||
CHAR(n) | ||
STRING | ||
DATE | ||
DATETIME | ||
TIMESTAMP | ||
TIMESTAMP_NTZ | ||
BOOLEAN | ||
ARRAY | ||
MAP | ||
STRUCT | ||
JSON |
Formats de compression pris en charge
Lorsque vous lisez ou écrivez des fichiers OSS compressés, vous devez inclure l'attribut with serdeproperties dans l'instruction CREATE TABLE. Pour plus d'informations, consultez la section Paramètres de l'attribut with serdeproperties.
Format de compression | com.aliyun.odps.CsvStorageHandler/ TsvStorageHandler (Built-in) | org.apache.hadoop.hive.serde2.OpenCSVSerde (Open-source) |
GZIP | ||
SNAPPY | ||
LZO | ||
ZSTD |
Évolution du schéma prise en charge
Opération | Prise en charge | Description |
Ajout de colonne |
| |
Suppression de colonne | Cette opération est déconseillée car elle peut entraîner une incompatibilité entre le schéma et les données. | |
Modification de l'ordre des colonnes | Cette opération est déconseillée car elle peut entraîner une incompatibilité entre le schéma et les données. | |
Modification du type de données d'une colonne | Pour obtenir la liste des conversions de types de données prises en charge, consultez Modification du type de données d'une colonne. | |
Renommage de colonne | ||
Modification du commentaire de colonne | Le commentaire doit être une chaîne valide d'une longueur maximale de 1 024 octets. Dans le cas contraire, une erreur se produit. | |
Modification de l'autorisation de valeur NULL d'une colonne | Cette opération n'est pas prise en charge. Les colonnes acceptent les valeurs NULL par défaut. |
Configuration des paramètres
Le schéma d'une table externe CSV ou TSV établit une correspondance avec les colonnes du fichier par position. Si le nombre de colonnes d'un fichier OSS ne correspond pas au nombre de colonnes du schéma de la table externe, utilisez le paramètre odps.sql.text.schema.mismatch.mode pour définir le traitement des lignes non concordantes.
-
Si
odps.sql.text.schema.mismatch.modeest défini sur truncate, les modifications de colonnes ont les effets suivants :Les données conformes au nouveau schéma sont lues normalement.
-
Les données existantes utilisant l'ancien schéma sont lues selon le nouveau schéma.
Par exemple, si vous ajoutez une colonne à une table, les données historiques de cette colonne apparaissent comme NULL lors de la lecture.
-
Si
odps.sql.text.schema.mismatch.modeest défini sur ignore, les modifications de colonnes ont les effets suivants :Les données conformes au nouveau schéma sont lues normalement.
-
Les données existantes utilisant l'ancien schéma sont lues selon le nouveau schéma.
Par exemple, si vous ajoutez une colonne à une table, les lignes entières de données historiques qui ne contiennent pas la nouvelle colonne sont ignorées lors de la lecture.
-
Si
odps.sql.text.schema.mismatch.modeest défini sur error, les modifications de colonnes ont les effets suivants :Les données conformes au nouveau schéma sont lues normalement.
-
Les données existantes utilisant l'ancien schéma sont lues selon le nouveau schéma.
Par exemple, si vous ajoutez une colonne à une table, une erreur se produit lorsque vous tentez de lire des données historiques qui ne contiennent pas la nouvelle colonne.
Création d'une table externe
Syntaxe
Built-in text parser
CSV format
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
<col_name> <data_type>,
...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
STORED BY 'com.aliyun.odps.CsvStorageHandler'
[WITH serdeproperties (
['<property_name>'='<property_value>',...]
)]
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];
TSV format
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
<col_name> <data_type>,
...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
STORED BY 'com.aliyun.odps.TsvStorageHandler'
[WITH serdeproperties (
['<property_name>'='<property_value>',...]
)]
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];
Built-in open-source parser
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
<col_name> <data_type>,
...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
[WITH serdeproperties (
['<property_name>'='<property_value>',...]
)]
STORED AS TEXTFILE
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];
Paramètres courants
Pour plus d'informations sur les paramètres courants, consultez la section Paramètres de syntaxe de base.
Paramètres spécifiques au format
Paramètres WITH SERDEPROPERTIES
Analyseur applicable | Paramètre | Cas d'utilisation | Description | Valeur | Valeur par défaut |
Analyseur de données texte intégré (CsvStorageHandler/TsvStorageHandler) | odps.text.option.gzip.input.enabled | Cette propriété permet de lire des fichiers CSV ou TSV compressés au format GZIP. | Propriété de compression CSV et TSV. Définissez cette propriété sur |
| False |
odps.text.option.gzip.output.enabled | Utilisez cette propriété pour écrire des données dans OSS au format compressé GZIP. | Propriété de compression CSV et TSV. Définissez cette propriété sur |
| False | |
odps.text.option.header.lines.count | Cette propriété sert à ignorer les N premières lignes d'un fichier CSV ou TSV dans OSS. | Spécifie le nombre de lignes d'en-tête à ignorer au début du fichier lors de la lecture des données. | Entier non négatif | 0 | |
odps.text.option.null.indicator | Permet de définir une chaîne personnalisée représentant une valeur NULL dans les données. | MaxCompute interprète la chaîne spécifiée comme une valeur Par exemple, pour interpréter | string | chaîne vide | |
odps.text.option.ignore.empty.lines | Définit le traitement des lignes vides dans un fichier CSV ou TSV. | Si la valeur est |
| True | |
odps.text.option.encoding | À utiliser lorsque le fichier de données n'emploie pas l'encodage UTF-8 par défaut. | L'encodage spécifié ici doit correspondre à l'encodage réel du fichier. Une incompatibilité entraîne l'échec de la lecture. |
| UTF-8 | |
odps.text.option.delimiter | Sert à spécifier le délimiteur de colonnes pour les fichiers CSV ou TSV. | Assurez-vous que le délimiteur spécifié sépare correctement les colonnes de votre fichier de données afin d'éviter tout désalignement. | Caractère unique | Virgule (,) | |
odps.text.option.use.quote | Nécessaire lorsqu'un champ d'un fichier CSV ou TSV contient des sauts de ligne (CRLF), des guillemets doubles ou le délimiteur de colonnes. | Lorsqu'un champ d'un fichier CSV contient un saut de ligne, un guillemet double (vous devez ajouter un autre |
| False | |
odps.sql.text.option.flush.header | Permet d'écrire un en-tête de table comme première ligne dans chaque bloc de fichiers sur OSS. | Cette propriété s'applique uniquement aux fichiers CSV. |
| False | |
odps.sql.text.schema.mismatch.mode | À utiliser lorsqu'une ligne du fichier de données possède un nombre de colonnes différent de celui du schéma de la table externe. | Définit la gestion des lignes dont le nombre de colonnes ne correspond pas au schéma de la table. Remarque : Cette fonctionnalité ne fonctionne pas si |
| error | |
odps.text.option.zstd.input.enabled | Active la lecture des fichiers CSV ou TSV compressés au format ZSTD. | Propriété de compression CSV et TSV. Définissez cette propriété sur True pour permettre à MaxCompute de lire les fichiers compressés en ZSTD. Sinon, l'opération de lecture échoue. |
| False | |
odps.text.option.zstd.output.enabled | Permet d'écrire des données dans OSS au format compressé ZSTD. | Propriété de compression CSV et TSV. Définissez cette propriété sur True pour compresser les données au format ZSTD lors de l'écriture vers OSS. Autrement, les données sont écrites sans compression. |
| False | |
odps.text.option.snappy.input.enabled | Ajoutez cette propriété pour lire des fichiers CSV ou TSV compressés avec SNAPPY (SnappyRawCodec). | Propriété de compression CSV et TSV. MaxCompute ne peut lire les fichiers compressés que si ce paramètre est défini sur True. Dans le cas contraire, la lecture échoue. |
| False | |
odps.text.option.snappy.output.enabled | Ajoutez cette propriété pour écrire des données dans OSS compressées avec SNAPPY (SnappyRawCodec). | Propriété de compression CSV et TSV. Lorsque ce paramètre est défini sur True, MaxCompute écrit les données dans OSS avec la compression SNAPPY. Sinon, les données sont écrites sans compression. |
| False | |
Analyseur de données open source intégré (OpenCSVSerde) | separatorChar | Spécifie le délimiteur de colonnes pour les données CSV stockées en tant que TEXTFILE. | Définit le délimiteur de colonnes. | Un caractère unique | Virgule (,) |
quoteChar | Utile lorsque les champs des données CSV contiennent des caractères spéciaux tels que le délimiteur ou des sauts de ligne. | Spécifie le caractère utilisé pour mettre les champs entre guillemets. | Un caractère unique | Aucun | |
escapeChar | Permet de spécifier le caractère d'échappement pour les données CSV stockées en tant que TEXTFILE. | Définit le caractère servant à échapper les caractères spéciaux au sein d'un champ. | Un caractère unique | Aucun |
Paramètres tblproperties
Analyseur applicable | Paramètre | Cas d'utilisation | Description | Valeur | Valeur par défaut |
Analyseur de données open source intégré (OpenCSVSerde) | skip.header.line.count | Permet d'ignorer les N premières lignes d'un fichier CSV stocké en tant que TEXTFILE. | Spécifie le nombre de lignes d'en-tête à ignorer au début du fichier lors de la lecture des données. | Entier non négatif | Aucun |
skip.footer.line.count | Permet d'ignorer les N dernières lignes d'un fichier CSV stocké en tant que TEXTFILE. | Spécifie le nombre de lignes de pied de page à ignorer à la fin du fichier lors de la lecture des données. | Entier non négatif | Aucun | |
mcfed.mapreduce.output.fileoutputformat.compress | Active la compression lors de l'écriture de données TEXTFILE vers OSS. | Propriété de compression TEXTFILE. Si la valeur est |
| False | |
mcfed.mapreduce.output.fileoutputformat.compress.codec | Spécifie le codec de compression à utiliser lors de l'écriture de données TEXTFILE compressées vers OSS. Pour la lecture de fichiers CSV/TSV compressés dont les noms comportent le suffixe .bz2, .deflate, .snappy, .gz ou .zstd, aucune configuration supplémentaire n'est requise. | Propriété de compression TEXTFILE. Définit la méthode de compression pour les fichiers de données TEXTFILE. |
| Aucun | |
odps.text.option.bad.row.skipping | Permet d'ignorer les données incorrectes dans les fichiers CSV stockés sur OSS. | Contrôle si MaxCompute ignore les lignes considérées comme des données incorrectes ou signale une erreur. |
| Aucun |
Liste d'autorisation et liste de blocage
Les tables externes OSS de MaxCompute prennent en charge le filtrage par liste d'autorisation et liste de blocage. En définissant les paramètres de liste d'autorisation et de liste de blocage dans tblproperties, vous pouvez filtrer les fichiers à lire dans un répertoire. Pour plus de détails, consultez Liste d'autorisation et liste de blocage.
Écriture de données
Pour plus de détails sur la syntaxe d'écriture dans MaxCompute, consultez Syntaxe d'écriture.
Requête et analyse
Consultez Syntaxe de requête pour plus de détails sur la syntaxe SELECT.
Reportez-vous à Optimisation des requêtes pour optimiser les plans de requête.
Voir BadRowSkipping pour plus de détails.
BadRowSkipping
La fonctionnalité BadRowSkipping permet d'ignorer les lignes incorrectes dans les données CSV qui provoqueraient autrement l'échec d'une requête. Ce paramètre contrôle la gestion des erreurs et n'affecte pas la manière dont le format de données sous-jacent est analysé.
Paramètres
-
Paramètre au niveau de la table :
odps.text.option.bad.row.skippingrigid: Force le saut des lignes. Ce paramètre ne peut pas être remplacé par des configurations au niveau de la session ou du projet.flexible: Active le saut des lignes. Ce paramètre est flexible, ce qui permet de le remplacer par des configurations au niveau de la session ou du projet.
-
Paramètres au niveau
session/project-
Le paramètre
odps.sql.unstructured.text.bad.row.skippingpeut remplacer un paramètre de tableflexible, mais pas un paramètrerigid.on: Active la fonctionnalité. Si la fonctionnalité n'est pas configurée pour la table, elle est activée par défaut.off: Désactive la fonctionnalité. Si la table est configurée en mode flexible, la fonctionnalité est désactivée. Sinon, le paramètre de la table est utilisé.<null> or invalid input: La configuration au niveau de la table est utilisée.
-
odps.sql.unstructured.text.bad.row.skipping.debug.num: Spécifie le nombre de résultats d'erreur à imprimer sur stdout dans Logview.La valeur maximale est 1000.
Si la valeur est <=0, cette fonctionnalité est désactivée.
Si la valeur est invalide, cette fonctionnalité est désactivée.
-
-
Interaction entre les paramètres au niveau de la session et les propriétés de la table
Propriété tbl
Indicateur de session
Résultat
rigid
on
On, Forcé à on
off
<null>, une valeur invalide ou le paramètre n'est pas configuré
flexible
on
On
off
Off, Désactivé par la session
<null>, une valeur invalide ou le paramètre n'est pas configuré
On
Non configuré
on
On, Activé par la session
off
Off
<null>, une valeur invalide ou le paramètre n'est pas configuré
Exemples
-
Préparez les données
Téléchargez le fichier de données de test csv_bad_row_skipping.csv, qui contient des lignes incorrectes, vers un répertoire dans OSS, tel que
oss-mc-test/badrow/. -
Créez les tables externes CSV
Les exemples suivants présentent trois scénarios basés sur différentes combinaisons de paramètres au niveau de la table et de la session.
Paramètre de table :
odps.text.option.bad.row.skipping = flexible | rigid | <not set>Indicateur de session :
odps.sql.unstructured.text.bad.row.skipping = on | off | <not set>
Paramètre non défini
-- No table-level parameter is set. Queries will fail on bad rows unless overridden by the session-level flag. CREATE EXTERNAL TABLE test_csv_bad_data_skipping_flag ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>';Saut flexible
-- The table is configured to skip bad rows, but this can be disabled by the session-level flag. CREATE EXTERNAL TABLE test_csv_bad_data_skipping_flexible ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>' tblproperties ( 'odps.text.option.bad.row.skipping' = 'flexible' -- Enables flexible skipping, which can be disabled at the session level. );Saut rigide
-- The table is configured to forcibly skip bad rows. This cannot be disabled at the session level. CREATE EXTERNAL TABLE test_csv_bad_data_skipping_rigid ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>' tblproperties ( 'odps.text.option.bad.row.skipping' = 'rigid' -- Forces skipping on. ); -
Vérifiez les résultats de la requête
Paramètre non défini
-- The following command enables skipping, but it is immediately overridden by the next command in this example. SET odps.sql.unstructured.text.bad.row.skipping=on; -- This command disables skipping and is the active setting for the SELECT query below, causing it to fail. SET odps.sql.unstructured.text.bad.row.skipping=off; -- You can use this command to print details of skipped rows when skipping is enabled. It has no effect here because the query fails. SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_flag;La requête échoue avec l'erreur suivante : FAILED: ODPS-0123131:User defined function exception
Saut flexible
-- The following command enables skipping, but it is immediately overridden by the next command in this example. SET odps.sql.unstructured.text.bad.row.skipping=on; -- This command disables skipping, overriding the table's 'flexible' setting. It is the active setting for the SELECT query below, causing it to fail. SET odps.sql.unstructured.text.bad.row.skipping=off; -- Print details of up to 10 bad rows at the session level. The maximum is 1,000. A value of 0 or less disables printing. SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_flexible;La requête échoue avec l'erreur suivante : FAILED: ODPS-0123131:User defined function exception
Saut rigide
-- This command is redundant because the 'rigid' setting already enforces skipping. SET odps.sql.unstructured.text.bad.row.skipping=on; -- This command attempts to disable skipping, but it is ignored because the 'rigid' table setting cannot be overridden. SET odps.sql.unstructured.text.bad.row.skipping=off; -- This command prints details for up to 10 bad rows that are skipped by the 'rigid' setting. SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_rigid;Le résultat suivant est retourné :
+------------+------------+ | a | b | +------------+------------+ | 1 | 26 | | 5 | 37 | +------------+------------+
Compatibilité flexible des types avec Smart Parse
Pour les tables externes au format CSV stockées dans OSS, MaxCompute SQL utilise les types de données 2.0 lors des opérations de lecture et d'écriture. Auparavant, seules les valeurs respectant un format strict étaient prises en charge. Cette fonctionnalité offre une compatibilité flexible des types, permettant de lire une grande variété de formats de valeurs depuis des fichiers CSV. Les règles d'analyse spécifiques sont détaillées ci-dessous.
Type | Input as string | Output as string | Description |
BOOLEAN |
Remarque Une opération |
| L'analyse échoue si la chaîne d'entrée ne correspond pas à l'une des valeurs prises en charge. |
TINYINT |
Remarque
|
| Entier 8 bits. Une erreur survient si la valeur se situe en dehors de la plage |
SMALLINT | Entier 16 bits. Une erreur survient si la valeur se situe en dehors de la plage | ||
INT | Entier 32 bits. Une erreur survient si la valeur se situe en dehors de la plage | ||
BIGINT | Entier 64 bits. Une erreur survient si la valeur se situe en dehors de la plage Remarque La valeur | ||
FLOAT |
Remarque
|
| Les valeurs spéciales (insensibles à la casse) incluent NaN, Inf, -Inf, Infinity et -Infinity. Une erreur survient si une valeur est hors plage. Si la précision dépasse la limite, la valeur est arrondie. |
DOUBLE |
Remarque
|
| Les valeurs spéciales (insensibles à la casse) incluent NaN, Inf, -Inf, Infinity et -Infinity. Une erreur survient si une valeur est hors plage. Si la précision dépasse la limite, la valeur est arrondie. |
DECIMAL (precision, scale) Exemple : DECIMAL(15,2) |
Remarque
|
| Une erreur survient si la partie entière contient plus de Une erreur est signalée. Si la partie fractionnaire dépasse l'échelle, la valeur est arrondie et tronquée. |
CHAR(n) Exemple : CHAR(7) |
|
| La longueur maximale est de 255. Si une chaîne d'entrée est plus courte que n, elle est complétée par des espaces de fin, mais ces espaces sont ignorés lors des comparaisons. Si une chaîne d'entrée est plus longue que n, elle est tronquée. |
VARCHAR(n) Exemple : VARCHAR(7) |
|
| La longueur maximale est de 65 535. Si une chaîne d'entrée est plus longue que n, elle est tronquée. |
STRING |
|
| La longueur maximale est de 8 Mo. |
DATE |
Remarque Vous pouvez également définir la propriété |
|
|
TIMESTAMP_NTZ Remarque OpenCsvSerde ne prend pas en charge ce type car il est incompatible avec le format de données Hive. |
|
|
|
DATETIME |
| En supposant que le fuseau horaire du système soit Asia/Shanghai :
|
|
TIMESTAMP |
| (En supposant que le fuseau horaire du système soit Asia/Shanghai)
|
|
-
Règles générales
Quel que soit le type de données, une chaîne vide dans le fichier de données CSV est analysée comme NULL lors de la lecture dans une table.
-
Types de données non pris en charge
Types complexes (STRUCT, ARRAY, MAP) : Non pris en charge. Les valeurs de ces types contiennent souvent des caractères tels que la virgule (
,), ce qui peut entrer en conflit avec les délimiteurs CSV courants et provoquer des échecs d'analyse.BINARY et INTERVAL : Actuellement non pris en charge. Si vous avez besoin de la prise en charge de ces types, contactez le support technique MaxCompute.
-
Types numériques (INT, DOUBLE, etc.)
Pour les types de données numériques tels que INT, SMALLINT, TINYINT, BIGINT, FLOAT, DOUBLE et DECIMAL, MaxCompute offre de vastes capacités d'analyse par défaut.
Si vous devez analyser uniquement des chaînes numériques de base, vous pouvez définir la propriété
odps.text.option.smart.parse.levelsurnaivedanstblproperties. En mode naïf, l'analyseur ne prend en charge que des formats simples comme "123" et "123.456". L'analyse d'autres formats de chaînes entraîne une erreur.
-
Types de date et d'heure (DATE, TIMESTAMP, etc.)
La classe
java.time.format.DateTimeFormattertraite les quatre types de date et d'heure :DATE, DATETIME, TIMESTAMP, and TIMESTAMP_NTZ.Formats par défaut : MaxCompute dispose de plusieurs formats d'analyse intégrés.
-
Formats personnalisés :
Vous pouvez définir plusieurs formats d'analyse et un format de sortie en configurant la propriété
odps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.formatdanstblproperties.Utilisez le symbole dièse (
#) pour séparer plusieurs modèles d'analyse.Les formats personnalisés priment sur les formats intégrés. Le premier modèle personnalisé est utilisé pour la sortie.
Exemple : Si vous définissez la chaîne de format personnalisée pour le type DATE comme
pattern1#pattern2#pattern3, MaxCompute peut analyser les chaînes correspondant àpattern1,pattern2oupattern3. Cependant, lors de l'écriture des données dans un fichier, la sortie utilisera toujours le format spécifié parpattern1. Pour plus d'informations, consultez DateTimeFormatter.
-
Note importante sur le modèle de fuseau horaire 'z'
Évitez d'utiliser 'z' (nom du fuseau horaire) dans les formats personnalisés, en particulier pour les utilisateurs situés en Chine, car cela prête à confusion.
Privilégiez plutôt 'x' (décalage de zone) ou 'VV' (ID de fuseau horaire) pour le modèle de fuseau horaire.
Exemple : 'CST' signifie généralement China Standard Time (UTC+8) en Chine. Cependant, lorsque
java.time.format.DateTimeFormatteranalyse 'CST', il l'interprète comme US Central Standard Time (UTC-6), ce qui peut entraîner des résultats d'entrée ou de sortie inattendus.
Logique de fractionnement des fichiers CSV
L'analyseur CSV/TSV intégré (OpenCSVSerde)
L'analyseur CSV/TSV intégré (OpenCSVSerde) exige que chaque ligne de données d'un fichier CSV soit séparée par \r\n ou des caractères similaires, et que les colonnes ne contiennent pas \r\n. La logique de fractionnement parallèle et d'intégrité des données est la suivante :
Tout d'abord, le fichier est fractionné selon la taille de split, ce qui peut couper certaines lignes en plein milieu.
Lorsque les workers suivants consomment les splits, tous les splits sauf le premier ignorent activement la première ligne partielle ou complète.
Chaque worker doit également consommer activement la dernière ligne partielle ou complète, même si celle-ci tombe dans la plage du split suivant.
Cet analyseur prend en charge le fractionnement parallèle, mais pas l'échappement des guillemets.
L'analyseur CSV open source (CsvStorageHandler / TsvStorageHandler)
L'analyseur CSV open source (CsvStorageHandler / TsvStorageHandler) prend en compte l'échappement des guillemets lors de la lecture des fichiers CSV/TSV et gère \r\n. Il peut traiter des scénarios où des caractères spéciaux, tels que des guillemets imbriqués ou \r\n, apparaissent entre guillemets.
Par exemple, dans les données "a\ra","b\nb","cc""cc", les caractères \r\n et les guillemets doubles peuvent être correctement analysés et restitués, permettant ainsi des valeurs multilignes. Toutefois, comme les positions réelles des sauts de ligne ne peuvent être déterminées que par l'analyse des données, le fichier ne peut pas être simplement fractionné par \r\n. Par conséquent, la consommation parallèle d'un seul fichier n'est pas prise en charge.
Si vous confirmez que les colonnes de données ne contiennent pas \r\n et que \r\n sert uniquement de délimiteur de ligne, vous pouvez activer le fractionnement parallèle en définissant odps.sql.unstructured.data.single.file.split.enabled. Dans ce cas, un fichier volumineux peut être divisé en plusieurs splits selon la taille de split, et l'Extracteur de texte intégré s'aligne automatiquement sur les limites de saut de ligne pour garantir l'intégrité des données.
Conclusion :
Si les données contiennent des \r\n qui ne peuvent pas être traités comme des délimiteurs de ligne, seul l'analyseur CSV/TSV intégré peut être utilisé.
Inversement, si vous devez fractionner un seul fichier volumineux en parallèle, seul l'analyseur CSV Serde open source peut être utilisé.
Exemples
Prérequis
Un projet MaxCompute. Consultez la rubrique Créer un projet MaxCompute.
Un bucket OSS situé dans la même région que votre projet MaxCompute. Reportez-vous aux rubriques Créer un bucket et Gérer les dossiers. MaxCompute peut créer automatiquement les dossiers OSS ; il est donc inutile de les créer manuellement avant d'exécuter des requêtes SQL.
Des permissions d'accès à OSS accordées via un compte Alibaba Cloud, un utilisateur Resource Access Management (RAM) ou un rôle RAM. Consultez la rubrique Autoriser l'accès en mode STS pour OSS.
La permission
CreateTablesur votre projet MaxCompute. Voir Permissions MaxCompute.
Créer une table externe OSS avec l'analyseur de texte intégré
Exemple 1 : Table non partitionnée
-
Associez la table externe au répertoire
Demo1/des données d'exemple. Exécutez la commande suivante pour créer une table externe OSS.CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external1 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo1/'; -- You can run the `desc extended mc_oss_csv_external1;` command to view the schema of the created OSS external table.Cet exemple utilise le rôle RAM
aliyunodpsdefaultrole. Si vous employez un autre rôle RAM, remplacezaliyunodpsdefaultrolepar le nom du rôle souhaité et accordez-lui les permissions nécessaires pour accéder à OSS. -
Interrogez la table externe non partitionnée.
SELECT * FROM mc_oss_csv_external1;La commande renvoie le résultat suivant :
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 1 | 51 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 4 | 30 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | W | | 1 | 5 | 47 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 6 | 9 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | S | | 1 | 7 | 53 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | | 1 | 8 | 63 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | SW | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | | 1 | 10 | 31 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | +------------+------------+------------+------------+------------------+-------------------+------------+----------------+ -
Écrivez des données dans la table externe non partitionnée et vérifiez la réussite de l'opération.
INSERT INTO mc_oss_csv_external1 VALUES(1,12,76,1,46.81006,-92.08174,'9/14/2014 0:10','SW'); SELECT * FROM mc_oss_csv_external1 WHERE recordId=12;La commande renvoie le résultat suivant :
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | SW | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+Vérifiez qu'un nouveau fichier apparaît dans le répertoire
Demo1/d'OSS.Une fois les données écrites, vous pouvez consulter le fichier de résultat généré
20250606054845430gpwnhakujm16_M1_1_0_0-0_TableSink1-0-.csv(0,046 Ko) dans le chemin OSS correspondant, ainsi que le fichier de données d'originevehicle.csv(0,45 Ko).
Exemple 2 : Table partitionnée
-
Associez la table externe au répertoire
Demo2/des données d'exemple. La commande ci-dessous crée une table externe OSS partitionnée.CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external2 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING ) PARTITIONED BY ( direction STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo2/'; -- You can run the `DESC EXTENDED mc_oss_csv_external2;` command to view the schema of the created external table.Cet exemple utilise le rôle RAM
aliyunodpsdefaultrole. Si vous employez un autre rôle RAM, remplacezaliyunodpsdefaultrolepar le nom du rôle souhaité et accordez-lui les permissions nécessaires pour accéder à OSS. -
Importez les données de partition. Lors de la création d'une table externe OSS partitionnée, l'importation des métadonnées de partition est obligatoire. Pour plus d'informations, consultez la rubrique Tables externes OSS.
MSCK REPAIR TABLE mc_oss_csv_external2 ADD PARTITIONS; -- This is equivalent to the following statement. ALTER TABLE mc_oss_csv_external2 ADD PARTITION (direction = 'N') PARTITION (direction = 'NE') PARTITION (direction = 'S') PARTITION (direction = 'SW') PARTITION (direction = 'W'); -
Interrogez la table externe partitionnée.
SELECT * FROM mc_oss_csv_external2 WHERE direction='NE';La commande renvoie le résultat suivant :
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ -
Écrivez des données dans la table externe partitionnée et assurez-vous de la réussite de l'écriture.
INSERT INTO mc_oss_csv_external2 PARTITION(direction='NE') VALUES(1,12,76,1,46.81006,-92.08174,'9/14/2014 0:10'); SELECT * FROM mc_oss_csv_external2 WHERE direction='NE' AND recordId=12;La commande renvoie le résultat suivant :
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+Confirmez la génération d'un nouveau fichier dans le répertoire
Demo2/direction=NEd'OSS.Le fichier de données de partition généré automatiquement
20250606062610590gocsdsoujm16_M1_1_0_0-0_TableSink1-0-.csvest visible dans la liste des fichiers OSS, ce qui confirme l'écriture réussie des données dans le chemin de partition correspondant.
Exemple 3 : Données compressées
Cet exemple illustre la création d'une table externe CSV compressée au format GZIP, ainsi que les opérations de lecture et d'écriture associées.
-
Créez une table interne et insérez des données de test pour préparer le test d'écriture ultérieur.
CREATE TABLE vehicle_test( vehicleid INT, recordid INT, patientid INT, calls INT, locationlatitute DOUBLE, locationlongtitue DOUBLE, recordtime STRING, direction STRING ); INSERT INTO vehicle_test VALUES (1,1,51,1,46.81006,-92.08174,'9/14/2014 0:00','S'); -
Créez une table externe CSV compressée au format GZIP et associez-la au répertoire
Demo3/(contenant des données compressées) des données d'exemple. La commande suivante crée cette table externe OSS.CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external3 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) PARTITIONED BY (dt STRING) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole', 'odps.text.option.gzip.input.enabled'='true', 'odps.text.option.gzip.output.enabled'='true' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo3/'; -- Import partition data. MSCK REPAIR TABLE mc_oss_csv_external3 ADD PARTITIONS; -- You can run the `DESC EXTENDED mc_oss_csv_external3;` command to view the schema of the created external table.Cet exemple utilise le rôle RAM
aliyunodpsdefaultrole. Si vous employez un autre rôle RAM, remplacezaliyunodpsdefaultrolepar le nom du rôle souhaité et accordez-lui les permissions nécessaires pour accéder à OSS. -
Utilisez un client MaxCompute pour lire les données depuis OSS :
RemarqueSi les données compressées dans OSS utilisent un format de données open source, ajoutez la commande
set odps.sql.hive.compatible=true;avant l'instruction SQL et envoyez-les ensemble pour exécution.--Enable a full table scan for the current session only. SET odps.sql.allow.fullscan=true; SELECT recordId, patientId, direction FROM mc_oss_csv_external3 WHERE patientId > 25;La commande renvoie le résultat suivant :
+------------+------------+------------+ | recordid | patientid | direction | +------------+------------+------------+ | 1 | 51 | S | | 3 | 48 | NE | | 4 | 30 | W | | 5 | 47 | S | | 7 | 53 | N | | 8 | 63 | SW | | 10 | 31 | N | +------------+------------+------------+ -
Lisez les données de la table interne et écrivez-les dans la table externe OSS.
Exécutez la commande
INSERT OVERWRITEouINSERT INTOsur une table externe depuis le client MaxCompute afin d'écrire des données vers OSS.INSERT INTO TABLE mc_oss_csv_external3 PARTITION (dt='20250418') SELECT * FROM vehicle_test;Après l'exécution réussie de la commande, consultez le fichier exporté dans le répertoire OSS.
Créer une table externe avec une ligne d'en-tête
Créez un répertoire Demo11 dans le bucket oss-mc-test des données d'exemple, puis exécutez les instructions suivantes :
--Create the external table.
CREATE EXTERNAL TABLE mf_oss_wtt
(
id BIGINT,
name STRING,
tran_amt DOUBLE
)
STORED BY 'com.aliyun.odps.CsvStorageHandler'
WITH serdeproperties (
'odps.text.option.header.lines.count' = '1',
'odps.sql.text.option.flush.header' = 'true'
)
LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo11/';
--Insert data.
INSERT OVERWRITE TABLE mf_oss_wtt VALUES (1, 'val1', 1.1),(2, 'value2', 1.3);
--Query data.
--When you create the table, you can define all columns as STRING. Otherwise, an error occurs when the header is read.
--Alternatively, add the 'odps.text.option.header.lines.count' = '1' parameter to the table definition to skip the header.
SELECT * FROM mf_oss_wtt;
Cet exemple utilise le rôle RAM aliyunodpsdefaultrole. Si vous employez un autre rôle RAM, remplacez aliyunodpsdefaultrole par le nom du rôle souhaité et accordez-lui les permissions nécessaires pour accéder à OSS.
La commande renvoie le résultat suivant :
+----------+--------+------------+
| id | name | tran_amt |
+----------+--------+------------+
| 1 | val1 | 1.1 |
| 2 | value2 | 1.3 |
+----------+--------+------------+
Créer une table externe avec des colonnes non concordantes
-
Créez un répertoire
demodans le bucketoss-mc-testdes données d'exemple, puis chargez le fichiertest.csv. Le contenu du fichiertest.csvest le suivant :1,kyle1,this is desc1 2,kyle2,this is desc2,this is two 3,kyle3,this is desc3,this is three, I have 4 columns -
Créez les tables externes.
-
Définissez le mode de gestion des lignes ayant un nombre de colonnes incohérent sur
TRUNCATE.-- Drop the table. DROP TABLE test_mismatch; -- Create the external table. CREATE EXTERNAL TABLE IF NOT EXISTS test_mismatch ( id string, name string, dect string, col4 string ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ('odps.sql.text.schema.mismatch.mode' = 'truncate') LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/'; -
Spécifiez le mode de gestion des lignes ayant un nombre de colonnes incohérent sur
IGNORE.-- Drop the table. DROP TABLE test_mismatch01; -- Create the external table. CREATE EXTERNAL TABLE IF NOT EXISTS test_mismatch01 ( id STRING, name STRING, dect STRING, col4 STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ('odps.sql.text.schema.mismatch.mode' = 'ignore') LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/'; -
Interrogez les données contenues dans ces tables.
-
Interrogez la table
test_mismatch.SELECT * FROM test_mismatch; --Returned result +----+-------+---------------+---------------+ | id | name | dect | col4 | +----+-------+---------------+---------------+ | 1 | kyle1 | this is desc1 | NULL | | 2 | kyle2 | this is desc2 | this is two | | 3 | kyle3 | this is desc3 | this is three | +----+-------+---------------+---------------+ -
Interrogez la table
test_mismatch01.SELECT * FROM test_mismatch01; --Returned result +----+-------+----------------+-------------+ | id | name | dect | col4 | +----+-------+----------------+-------------+ | 2 | kyle2 | this is desc2 | this is two +----+-------+----------------+-------------+
-
-
Créer une table externe avec l'analyseur open source
Cet exemple montre comment utiliser l'analyseur open source intégré pour créer une table externe OSS permettant de lire un fichier séparé par des virgules, tout en ignorant les lignes d'en-tête et de pied de page.
-
Créez un répertoire
demo-testdans le bucketoss-mc-testdes données d'exemple, puis chargez le fichier test.csv.Le fichier de test contient les données suivantes :
1,1,51,1,46.81006,-92.08174,9/14/2014 0:00,S 1,2,13,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,3,48,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,4,30,1,46.81006,-92.08174,9/14/2014 0:00,W 1,5,47,1,46.81006,-92.08174,9/14/2014 0:00,S 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00,S 1,7,53,1,46.81006,-92.08174,9/15/2014 0:00,N 1,8,63,1,46.81006,-92.08174,9/15/2014 0:00,SW 1,9,4,1,46.81006,-92.08174,9/15/2014 0:00,NE 1,10,31,1,46.81006,-92.08174,9/15/2014 0:00,N -
Créez la table externe, définissez la virgule comme séparateur et configurez les paramètres pour ignorer les lignes d'en-tête et de pied de page.
CREATE EXTERNAL TABLE ext_csv_test08 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT serde 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH serdeproperties ( "separatorChar" = "," ) stored AS textfile location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/***/' -- Set parameters to ignore the header and footer rows. TBLPROPERTIES ( "skip.header.line.COUNT"="1", "skip.footer.line.COUNT"="1" ) ; -
Lisez les données depuis la table externe.
SELECT * FROM ext_csv_test08; -- The result includes 8 rows of data because the header and footer rows are ignored. +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 4 | 30 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | W | | 1 | 5 | 47 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 6 | 9 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | S | | 1 | 7 | 53 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | | 1 | 8 | 63 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | SW | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
Créer une table externe CSV avec des types temporels personnalisés
Pour plus de détails sur les formats d'analyse et de sortie des types temporels personnalisés en CSV, consultez la rubrique Compatibilité flexible des types avec Smart Parse.
-
Créez une table externe CSV utilisant divers types de données temporelles, tels que
DATE,DATETIME,TIMESTAMPetTIMESTAMP_NTZ.CREATE EXTERNAL TABLE test_csv ( col_date DATE, col_datetime DATETIME, col_timestamp TIMESTAMP, col_timestamp_ntz TIMESTAMP_NTZ ) STORED BY 'com.aliyun.odps.CsvStorageHandler' LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/' TBLPROPERTIES ( 'odps.text.option.date.io.format' = 'MM/dd/yyyy', 'odps.text.option.datetime.io.format' = 'yyyy-MM-dd-HH-mm-ss x', 'odps.text.option.timestamp.io.format' = 'yyyy-MM-dd HH-mm-ss VV', 'odps.text.option.timestamp_ntz.io.format' = 'yyyy-MM-dd HH:mm:ss.SS' ); INSERT OVERWRITE test_csv VALUES(DATE'2025-02-21', DATETIME'2025-02-21 08:30:00', TIMESTAMP'2025-02-21 12:30:00', TIMESTAMP_NTZ'2025-02-21 16:30:00.123456789'); -
Après l'insertion des données, le contenu du fichier CSV se présente comme suit :
02/21/2025,2025-02-21-08-30-00 +08,2025-02-21 12-30-00 Asia/Shanghai,2025-02-21 16:30:00.12 -
Interrogez à nouveau les données pour visualiser le résultat.
SELECT * FROM test_csv;La commande renvoie le résultat suivant :
+------------+---------------------+---------------------+------------------------+ | col_date | col_datetime | col_timestamp | col_timestamp_ntz | +------------+---------------------+---------------------+------------------------+ | 2025-02-21 | 2025-02-21 08:30:00 | 2025-02-21 12:30:00 | 2025-02-21 16:30:00.12 | +------------+---------------------+---------------------+------------------------+
FAQ
Erreur de non-concordance du nombre de colonnes
-
Symptôme
Cette erreur survient lorsque le nombre de colonnes d'une ligne dans un fichier CSV ou TSV ne correspond pas à celui défini dans le DDL de la table externe. MaxCompute signale alors une erreur similaire à
FAILED: ODPS-0123131:User defined function exception - Traceback:java.lang.RuntimeException: SCHEMA MISMATCH:xxx. -
Résolution
Vous pouvez contrôler le traitement de cette non-concordance par MaxCompute en définissant le paramètre
odps.sql.text.schema.mismatch.modeau niveau de la session :SET odps.sql.text.schema.mismatch.mode=error: fait échouer la requête en cas de non-concordance du nombre de colonnes. Il s'agit du comportement par défaut.SET odps.sql.text.schema.mismatch.mode=truncate: si une ligne comporte plus de colonnes que prévu dans le DDL de la table externe, les colonnes excédentaires sont ignorées. À l'inverse, si elle en comporte moins, les colonnes manquantes reçoivent la valeur NULL.