Partition operations for OSS external tables
This topic describes how to manage partitions for OSS external tables. The operations include loading partitions, adding partitions, writing data to partitions, dropping partitions, and using the Keyless Partition feature, which allows creating partition paths that omit the partition key name.
Use cases
When you create a partitioned OSS external table, you must also load the partition data.
To automatically parse the OSS directory structure, identify partitions, and add partition metadata to the OSS external table, see Load partitions (MSCK).
To manually add partition metadata to the OSS external table, see Add partitions.
To write data to a partition in an OSS external table, see Write data to partitions.
To drop one or more partitions from an OSS external table, see Drop partitions.
To write data to an OSS partition path that does not include the partition key by using an OSS external table, see Keyless Partition.
To retrieve data from the maximum partition of an OSS external table, see Use the MAX_PT function.
Load partitions (MSCK)
Scenarios
When you create a partitioned OSS external table, you must also load its partition data. MaxCompute automatically discovers partitions by parsing the OSS directory structure and adds the partition metadata to the external table.
The MSCK command is suitable for one-time operations to load all historical partitions. MaxCompute automatically discovers and adds partitions to the OSS external table based on the partition directory specified during table creation. This eliminates the need to add them individually.
If you are adding only a few new partitions to a table that already has many, frequently running the MSCK command is inefficient. It repeatedly scans the entire OSS directory and triggers metadata updates, which degrades performance. For incremental partition updates, it is recommended that you add partitions manually instead.
Syntax
MSCK REPAIR TABLE <mc_oss_extable_name>;
MSCK REPAIR TABLE <mc_oss_extable_name> ADD PARTITIONS [WITH PROPERTIES (key:VALUE, key:VALUE ...)];Examples
This section uses a partitioned CSV external table as an example. The MSCK command is used in the same way for other OSS external table formats.
Prepare the partition data
Log on to the Object Storage Service (OSS) console.
In the bucket, create a
Demo2directory. In this directory, create subdirectories based on the partition columndirection(direction=N,direction=NE,direction=S,direction=SW, anddirection=W), and upload the corresponding data files (vehicle1.csv, vehicle2.csv, vehicle3.csv, vehicle4.csv, and vehicle5.csv) to each subdirectory. For more information, see Appendix: Prepare sample data.
Create a partitioned OSS external table
CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external2 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitude DOUBLE, locationLongitude 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-<region>-internal.aliyuncs.com/<bucket>/Demo2/';Load partitions
MSCK REPAIR TABLE mc_oss_csv_external2 ADD PARTITIONS;Query the OSS external table
SELECT * FROM mc_oss_csv_external2 WHERE direction='NE'; -- The following result is returned: +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+ | vehicleid | recordid | patientid | calls | locationlatitude | locationlongitude | 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 | +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+
Add partitions
Scenarios
If an OSS external table is a partitioned table, you must perform an additional operation to load its partition data. To manually add the partition information, you can use the ALTER TABLE ADD PARTITION command.
This method is ideal for adding new partitions on a regular basis after the historical partitions are loaded. By adding a partition before writing data to it, you ensure the external table can read the new data immediately, without a separate metadata refresh step.
Syntax
ALTER TABLE <mc_oss_extable_name>
ADD PARTITION (<col_name>=<col_value>)[
PARTITION (<col_name>=<col_value>)...][location URL];The values of
col_nameandcol_valuemust align with the name of the directory that contains the partition data files. OneADD PARTITIONclause corresponds to one subdirectory, and multipleADD PARTITIONclauses are required for multiple OSS subdirectories.For example, in the OSS directory structure for the partition data files,
col_namecorresponds todirection, andcol_valuecorresponds toN,NE,S,SW, orW.Demo2/ ├── direction=N/ ├── direction=NE/ ├── direction=S/ ├── direction=SW/ └── direction=W/
Examples
This section uses a partitioned CSV external table as an example. The method for adding partitions is the same for other OSS external table formats.
Prepare the partition data
Log on to the Object Storage Service (OSS) console.
In the bucket, create a
Demo2directory. In this directory, create subdirectories based on the partition columndirection(direction=N,direction=NE,direction=S,direction=SW, anddirection=W), and upload the corresponding data files (vehicle1.csv, vehicle2.csv, vehicle3.csv, vehicle4.csv, and vehicle5.csv) to each subdirectory. For more information, see Appendix: Prepare sample data.
Create a partitioned OSS external table
CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external3 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitude DOUBLE, locationLongitude 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-<region>-internal.aliyuncs.com/<bucket>/Demo2/';Add partitions
ALTER TABLE mc_oss_csv_external3 ADD PARTITION (direction='N') PARTITION (direction='NE') PARTITION (direction='S') PARTITION (direction='SW') PARTITION (direction='W');Query the OSS external table
SELECT * FROM mc_oss_csv_external3 WHERE direction='NE'; -- The following result is returned: +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+ | vehicleid | recordid | patientid | calls | locationlatitude | locationlongitude | 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 | +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+
Write data to partitions
Static partition write
Scenarios
Use the following operations to write data to an OSS external table by using a static partition. For more information, see Insert or overwrite data (INSERT INTO | INSERT OVERWRITE).
Syntax
INSERT {INTO|OVERWRITE} TABLE <mc_oss_extable_name>
PARTITION (<pt_spec>) [(<col_name> [,<col_name> ...)]]
<select_statement> FROM <from_statement>;Examples
This section uses a partitioned CSV external table as an example. The method for writing data is the same for other OSS external table formats.
Create a partitioned OSS external table
CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external5 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitude DOUBLE, locationLongitude 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-<region>-internal.aliyuncs.com/<bucket>/mc_oss_csv_external5';Write data to a static partition
INSERT INTO mc_oss_csv_external5 PARTITION (direction='SW') VALUES (1, 14, 76, 1, 46.81006, -92.08174, '9/14/2014 0:10'); INSERT INTO mc_oss_csv_external5 PARTITION (direction='S') VALUES (1, 89, 76, 1, 46.81006, -92.08174, '9/14/2014 0:10');Verify the result
SET odps.sql.allow.fullscan=true; SELECT * FROM mc_oss_csv_external5; -- The following result is returned: +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+ | vehicleid | recordid | patientid | calls | locationlatitude | locationlongitude | recordtime | direction | +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+ | 1 | 89 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | S | | 1 | 14 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | SW | +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+
Dynamic partition write
Scenarios
Use the following operations to write data to an OSS external table by using a dynamic partition. For more information, see Insert or overwrite data into dynamic partitions (DYNAMIC PARTITION).
Syntax
INSERT {INTO|OVERWRITE} TABLE <table_name> PARTITION (<ptcol_name>[, <ptcol_name> ...])
<select_statement> FROM <from_statement>;Examples
This section uses a partitioned CSV external table as an example. The method for writing data is the same for other OSS external table formats.
Prepare a test table
CREATE TABLE IF NOT EXISTS vehicle_test ( vehicleid INT, recordid INT, patientid INT, calls INT, locationlatitude DOUBLE, locationlongitude DOUBLE, recordtime STRING, direction STRING ); INSERT INTO vehicle_test VALUES (1, 1, 51, 1, 46.81006, -92.08174, '9/14/2014 0:00', 'S'); INSERT INTO vehicle_test VALUES (1, 2, 13, 1, 46.81006, -92.08174, '9/14/2014 0:00', 'NE'); INSERT INTO vehicle_test VALUES (1, 3, 48, 1, 46.81006, -92.08174, '9/14/2014 0:00', 'NE'); INSERT INTO vehicle_test VALUES (1, 4, 30, 1, 46.81006, -92.08174, '9/14/2014 0:00', 'W'); INSERT INTO vehicle_test VALUES (1, 5, 47, 1, 46.81006, -92.08174, '9/14/2014 0:00', 'S');Create a partitioned OSS external table
CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external6 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitude DOUBLE, locationLongitude 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-<region>-internal.aliyuncs.com/<bucket>/mc_oss_csv_external6';Write data using dynamic partitions
INSERT INTO mc_oss_csv_external6 PARTITION(direction) SELECT * FROM vehicle_test;Verify the result
SET odps.sql.allow.fullscan=true; SELECT * FROM mc_oss_csv_external6; -- The following result is returned: +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+ | vehicleid | recordid | patientid | calls | locationlatitude | locationlongitude | recordtime | direction | +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+ | 1 | 4 | 30 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | W | | 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 | 1 | 51 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 5 | 47 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | +-----------+----------+-----------+-------+------------------+-------------------+------------+-----------+
Drop partitions
Scenarios
You can drop one or more partitions from a partitioned OSS external table. For more information, see Partition operations.
Syntax
ALTER TABLE <mc_oss_extable_name> DROP [IF EXISTS] PARTITION <pt_spec>[, PARTITION <pt_spec>...];Examples
View the partition list of the sample table
mc_oss_csv_external3from the Add a partition example.SHOW PARTITIONS mc_oss_csv_external3; -- The following result is returned: direction=N direction=NE direction=S direction=SW direction=W OKDrop the
direction=Sanddirection=SWpartitions.ALTER TABLE mc_oss_csv_external3 DROP IF EXISTS PARTITION (direction = 'S'), PARTITION (direction = 'SW');View the partition list again to confirm that the
direction=Sanddirection=SWpartitions have been dropped.SHOW PARTITIONS mc_oss_csv_external3; -- The following result is returned: direction=N direction=NE direction=W OK
Keyless Partition
Scenarios
In this scenario, when you write data to a partitioned OSS external table, the generated OSS partition directory includes the partition key and value (for example, dt=20250724). If you want to write to an OSS partition path that does not include the partition key, you can use the Keyless Partition feature.
Limitations
If you specify a fixed
valuewhen writing data to an external table by using dynamic partitions, the Keyless Partition parameter has no effect. An OSS directory is generated in the<pt_col_name>=<pt_col_value>format, and you cannot read the data from this directory. For example,INSERT OVERWRITE ext_tb PARTITION(dt) VALUES(1, 'xxx','20250724'), (2, 'xxx','20250724')This feature is not supported for Paimon, Hudi, and Delta Lake external tables.
Syntax
Add the TBLPROPERTIES parameter when you create an external table. The following is an example for a CSV external table.
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('odps.external.output.partition.keys.omitted' = 'true'); -- When this parameter is true, the output OSS partition directory does not include the partition key.Examples
This section uses a partitioned CSV external table as an example. The method is the same for other formats.
Create a partitioned CSV external table
CREATE EXTERNAL TABLE ext_csv_test03 ( id INT, name STRING ) PARTITIONED BY (dt STRING) STORED BY 'com.aliyun.odps.CsvStorageHandler' LOCATION 'oss://oss-cn-<region>-internal.aliyuncs.com/<bucket>/keyless_partition/ext_csv_test03/' TBLPROPERTIES('odps.external.output.partition.keys.omitted' = 'true');Write constant data to a static partition
INSERT INTO ext_csv_test03 PARTITION (dt='20250724') VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); SELECT * FROM ext_csv_test03; -- The following result is returned: +------+------+----------+ | id | name | dt | +------+------+----------+ | 1 | aaa | 20250724 | | 2 | bbb | 20250724 | | 3 | ccc | 20250724 | +------+------+----------+The directory generated by OSS is as follows: the
20250724directory does not contain the partition keydt=.ext_csv_test03/ └── 20250724/Write data using a single dynamic partition value
Formally, this is a dynamic partition write, but because the data for the partition column in the
valuesclause has only one value,'xxx', it is considered a partially static and partially dynamic partition write in MaxCompute's logic.INSERT OVERWRITE ext_csv_test03 PARTITION(dt) VALUES (1, 'xxx','20250724'), (2, 'xxx','20250724'); SELECT * FROM ext_csv_test03; -- The following result is returned: -- Because the generated OSS partition directory is in an unexpected format, the newly inserted data cannot be queried. Only the data from the static write in Step 2 is returned. +------+------+----------+ | id | name | dt | +------+------+----------+ | 1 | aaa | 20250724 | | 2 | bbb | 20250724 | | 3 | ccc | 20250724 | +------+------+----------+As you can see in the directory generated by OSS, the generated
dt=20250724directory contains the partition keydt, so the syntax used in this scenario is incorrect.ext_csv_test03/ ├── 20250724/ └── dt=20250724/Write constant data using dynamic partitions
INSERT OVERWRITE ext_csv_test03 PARTITION(dt) VALUES (1, 'xxx','20250725'), (2, 'yyy','20250726'); SELECT * FROM ext_csv_test03; -- The following result is returned: +------+------+----------+ | id | name | dt | +------+------+----------+ | 2 | yyy | 20250726 | | 1 | xxx | 20250725 | | 1 | aaa | 20250724 | | 2 | bbb | 20250724 | | 3 | ccc | 20250724 | +------+------+----------+The directories generated by OSS are as follows. The generated
20250725and20250726directories do not contain the partition keydt=.ext_csv_test03/ ├── 20250724/ ├── 20250725/ └── 20250726/Write data from a SELECT clause using dynamic partitions.
Prepare a test table.
CREATE TABLE table03 (id INT, name STRING, dt STRING); INSERT INTO table03 VALUES (6, 'fff', '20250725'), (7, 'ggg', '20250725'), (8, 'hhh', '20250723');Write data from the test table via a SELECT clause
INSERT OVERWRITE ext_csv_test03 PARTITION(dt) SELECT * FROM table03; SELECT * FROM ext_csv_test03; -- The following result is returned: +------+------+----------+ | id | name | dt | +------+------+----------+ | 2 | yyy | 20250726 | | 8 | hhh | 20250723 | | 6 | fff | 20250725 | | 7 | ggg | 20250725 | | 1 | aaa | 20250724 | | 2 | bbb | 20250724 | | 3 | ccc | 20250724 | +------+------+----------+As you can see from the directories generated by OSS, the
20250723and20250725directories do not contain the partition keydt=.ext_csv_test03/ ├── 20250723/ ├── 20250724/ ├── 20250725/ └── 20250726/
Use the MAX_PT function
Scenarios
You can use the MAX_PT function to query data from the maximum partition that contains data in an OSS external table. For more information, see MAX_PT.
Considerations
When an OSS external table has multi-level partitions,
MAX_PTreturns only the maximum partition value among the first-level partitions that contain data, and this partition can be listed by usingSHOW PARTITIONS.If no partitions containing files are found in the OSS directory, the
MAX_PTfunction returns an error.Executing the
MAX_PTfunction on a non-partitioned table reports an error.
Syntax
SELECT * FROM <mc_oss_extable_name>
WHERE <pt_col_name> = MAX_PT("<mc_oss_extable_name>");
-- You can also use the following syntax.
SELECT * FROM <mc_oss_extable_name>
WHERE <pt_col_name> = (SELECT MAX(<pt_col_name>) FROM <mc_oss_extable_name>);Examples
This section uses a partitioned CSV external table as an example. The MAX_PT function works the same way for other OSS external table formats.
Create a partitioned OSS external table and write data to it
CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external9 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitude DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) PARTITIONED BY ( y STRING, m STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH SERDEPROPERTIES ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) LOCATION 'oss://oss-cn-<region>-internal.aliyuncs.com/<bucket>/mc_oss_csv_external9'; INSERT INTO mc_oss_csv_external9 PARTITION(y='2023', m='03') VALUES (1, 89, 76, 1, 46.81606, -92.08174, '9/14/2014 0:10', 'SW'); INSERT INTO mc_oss_csv_external9 PARTITION(y='2023', m='02') VALUES (1, 14, 76, 1, 47.90836, -92.08174, '9/14/2014 0:10', 'W'); INSERT INTO mc_oss_csv_external9 PARTITION(y='2022', m='03') VALUES (1, 56, 76, 1, 48.81748, -92.08174, '9/14/2014 0:10', 'S'); INSERT INTO mc_oss_csv_external9 PARTITION(y='2022', m='02') VALUES (1, 78, 76, 1, 49.81678, -92.08174, '9/14/2014 0:10', 'SE');OSS partition directory
mc_oss_csv_external9/ ├── y=2022/ ├── m=02/ └── d.csv └── m=03/ └── c.csv └── y=2023/ ├── m=02/ └── b.csv └── m=03/ └── a.csvFor an OSS external table with multi-level partitions, the return value of
MAX_PTvaries depending on which directory is empty, as follows.When all OSS partition directories are not empty, the
MAX_PTfunction returns the first-level partition2023.-- Query the maximum partition of the external table. SELECT MAX_PT("mc_oss_csv_external9"); -- The following result is returned: +-----+ | _c0 | +-----+ | 2023 | +-----+When the top-level directory part of the OSS partition directory is empty, the
MAX_PTfunction returns the first-level partition2023.mc_oss_csv_external9/ ├── y=2022/ ├── m=02/ └── d.csv └── m=03/ └── c.csv └── y=2023/ ├── m=02/ └── b.csv └── m=03/ -- Empty-- Query the maximum partition of the external table. SELECT MAX_PT("mc_oss_csv_external9"); -- The following result is returned: +-----+ | _c0 | +-----+ | 2023 | +-----+When the largest first-level directory of an OSS partition directory is completely empty, the
MAX_PTfunction returns the first-level partition2022.mc_oss_csv_external9/ ├── y=2022/ ├── m=02/ └── d.csv └── m=03/ └── c.csv └── y=2023/ ├── m=02/ -- Empty └── m=03/ -- Empty-- Query the maximum partition of the external table. SELECT MAX_PT("mc_oss_csv_external9"); -- The following result is returned: +-----+ | _c0 | +-----+ | 2022 | +-----+When all directories in the partition directory are completely empty, the
MAX_PTfunction reports an error.SELECT MAX_PT("mc_oss_csv_external9"); -- The following error is returned: FAILED: ODPS-0130071:[1,8] Semantic analysis exception - encounter runtime exception while evaluating function MAX_PT, detailed message: table "project.default.mc_oss_csv_external9" has no partitions or none of the partitions have any data