MaxCompute can automatically partition tables based on the data ingestion time. For these tables, known as ingestion-time partitioned tables, MaxCompute captures the ingestion time and uses a specified time function, such as `TRUNC_TIME`, to generate values for partition key columns. This topic describes how to use these tables.
Features
MaxCompute provides two types of partitioned tables: standard partitioned tables and auto-partitioned tables. You can choose the table type based on how you want to generate partition key columns for your scenario. For more information, see Partitioned table overview.
To use an ingestion-time partitioned table, you must specify a pseudo-column named _partitiontime with a time-based data type in the table definition. The system truncates the ingestion time for each row to a specific time granularity, such as hour, day, month, or year. It then uses this truncated time to automatically generate the value for the _partitiontime pseudo-column.
For example, if you create an ingestion-time partitioned table that generates partitions by the hour and write data at the following times:
Data ingestion time (UTC+8) | Generated _PARTITIONTIME column (TIMESTAMP) | Generated partition (STRING) |
2025-06-18 17:22:00 | 2025-06-18 17:00:00 | 2025-06-18 09:00:00 |
2025-06-18 17:40:00 | 2025-06-18 17:00:00 | 2025-06-18 09:00:00 |
2025-06-18 18:31:00 | 2025-06-18 18:00:00 | 2025-06-18 10:00:00 |
In the preceding example, the ingestion-time partitioned table generates partitions by the hour. The system truncates the data ingestion time to populate the _partitiontime column. This value is then converted to a UTC string and used as the value for the partition key column.
Limits
Ingestion-time partitioned tables support only a single partition key column. Multi-level partitioning is not supported.
The partition key column of an ingestion-time partitioned table has a default data type of STRING. You cannot change this data type.
The auto-partitioning feature based on time functions and data ingestion time is supported only for data writes that use MaxCompute SQL. Other data ingestion methods, such as the Flink connector, are not supported.
When truncating the ingestion time, only the TRUNC_TIME function is supported. This function converts the local time to UTC before it truncates the value. Because of this conversion, the time zone affects the final value of the STRING partition key column. You should set your project's time zone to UTC by running the
SET odps.sql.timezone=UTC;statement.
Usage
Create an ingestion-time partitioned table
Syntax
Use the following syntax to create an ingestion-time partitioned table.
CREATE [OR REPLACE] TABLE [IF NOT EXISTS] <table_name> (_partitiontime <data_type>, <col_name><data_type>... )
[COMMENT <table_comment>]
AUTO PARTITIONED BY (<auto_partition_expression> [AS <auto_partition_column_name>]);
TBLPROPERTIES('ingestion_time_partition'='true');Parameters:
Parameter | Required | Description |
table_name | Yes | The name of the table to create. |
_partitiontime | Yes | A pseudo-column for the truncated ingestion time. The column name cannot be changed. The supported data types are TIMESTAMP and TIMESTAMP_NTZ. |
col_name | Yes | The column name. |
data_type | Yes | The data type of the column. |
table_comment | No | The comment of the table. |
TBLPROPERTIES('ingestion_time_partition'='true') | Yes | Specifies that the table to be created is an ingestion-time partitioned table. The partition key column is generated based on the data ingestion time. |
auto_partition_expression | Yes | The expression that defines the calculation for the partition key column. Currently, only the TRUNC_TIME function is supported to calculate the Note When you create an ingestion-time partitioned table, the system automatically gets the data ingestion time. It then truncates this time using the TRUNC_TIME function to generate the value of the partition key column. |
auto_partition_column_name | No | The name of the generated partition key column. If you do not specify a name, the system uses Note After the partition expression is calculated, a STRING partition key column is generated based on the result. You cannot directly modify the data type or values of this column. |
Examples
Example 1
This example creates an ingestion-time partitioned table named
ingestion_sale_detail_hourlythat is partitioned by the hour. The table definition specifies a pseudo-column named_partitiontimeof the TIMESTAMP type. When data is written to the table, the system automatically obtains the data ingestion time. It then populates the_partitiontimepseudo-column based on the hourly granularity specified in the DDL statement. The value of the partition key columnsale_timeis then generated based on this result.-- After the table is created, the system automatically obtains the data ingestion time when data is written. It truncates _partitiontime by the hour, generates a partition key column named sale_time, and partitions the table based on this column. CREATE TABLE IF NOT EXISTS ingestion_sale_detail_hourly( shop_name STRING, total_price DOUBLE, _partitiontime TIMESTAMP) AUTO PARTITIONED BY (TRUNC_TIME(_partitiontime, 'hour') AS sale_time) TBLPROPERTIES('ingestion_time_partition'='true');The
ingestion_sale_detail_hourlytable created in the preceding example contains four columns. Thesale_timecolumn is an automatically generated partition key column of the STRING type. You can run theDESC ingestion_sale_detail_hourly;statement to view the table information. The following is a sample result:+------------------------------------------------------------------------------------+ | Owner: ALIYUN$test**** | | Project: xxxxxxx | | Schema: default | | TableComment: | +------------------------------------------------------------------------------------+ | CreateTime: 2025-06-16 14:59:40 | | LastDDLTime: 2025-06-16 14:59:40 | | LastModifiedTime: 2025-06-16 14:59:40 | +------------------------------------------------------------------------------------+ | InternalTable: YES | Size: 0 | +------------------------------------------------------------------------------------+ | Native Columns: | +------------------------------------------------------------------------------------+ | Field | Type | Label | Comment | +------------------------------------------------------------------------------------+ | shop_name | string | | | | | total_price | double | | | | _partitiontime | timestamp | | | +------------------------------------------------------------------------------------+ | Partition Columns: | +------------------------------------------------------------------------------------+ | sale_time | string | | +------------------------------------------------------------------------------------+Example 2
This example creates an ingestion-time partitioned table named
ingestion_sale_detail_dailythat is partitioned by the day. If the partition granularity is by day, an additional pseudo-column named_partitiondateof the DATE type is also generated, along with the_partitiontimepseudo-column.CREATE TABLE IF NOT EXISTS ingestion_sale_detail_daily( shop_name STRING, total_price DOUBLE, _partitiontime TIMESTAMP) AUTO PARTITIONED BY (TRUNC_TIME(_partitiontime, 'day') AS sale_date) TBLPROPERTIES('ingestion_time_partition'='true');NoteYou can run the
SELECT *, _partitiondate FROM ingestion_sale_detail_daily;command to view the_partitiondatepseudo-column.To view the partition generation logic for the ingestion-time partition key column, you can use the SHOW CREATE TABLE statement.
Write data to an ingestion-time partitioned table
When you use an SQL statement to write data to an ingestion-time partitioned table, you can specify a value for the _partitiontime pseudo-column. However, the time granularity of the _partitiontime value must match the granularity defined in the `CREATE TABLE` statement.
If you do not specify a value for _partitiontime, the system automatically uses the time when the data is written to MaxCompute. It then uses the specified time function to populate the _partitiontime pseudo-column and generate the value for the partition key column, and then partitions the data accordingly.
Examples:
The following examples show how to write data to the ingestion_sale_detail_hourly and ingestion_sale_detail_daily tables created in the Examples section.
Example 1
When you insert data, do not specify a value for the
_partitiontimepseudo-column.INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price) VALUES ('shanghai_shop',10001.1), ('chongqin_shop',20002.2), ('hangzhou_shop',30003.3), ('shenzhen_shop',40004.4);Example 2
When you insert data, you can specify a value for the
_partitiontimepseudo-column. The time granularity of the_partitiontimevalue must match the specified partition granularity, which is `hour`.Valid example: Specify
'2025-06-15 14:00:00'as the value for the_partitiontimecolumn.INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price,_partitiontime) VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-15 14:00:00'), ('chengdu_shop',60006.6,TIMESTAMP '2025-06-14 05:00:00');Invalid example: Specify
'2025-06-15 14:30:00'as the value for the_partitiontimecolumn. This value does not match the hourly partition granularity.INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price,_partitiontime) VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-15 14:30:00');The following error message is returned:
FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: SQL Runtime Unretryable Error: ODPS-0121095:Invalid argument - illegal ingestion time: 2025-06-15 14:30:00
Example 3
When the partition granularity is by day, you can specify a value only for the
_partitiontimepseudo-column. You cannot specify a value for the_partitiondatepseudo-column.Valid example: Specify
'2025-06-18 00:00:00'as the value for the_partitiontimecolumn.INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiontime) VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-18 00:00:00');Invalid examples:
Specify
'2025-06-15 14:00:00'as the value for the_partitiontimecolumn. This value does not match the daily partition granularity.INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiontime) VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-18 14:00:00');The following error message is returned:
FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: SQL Runtime Unretryable Error: ODPS-0121095:Invalid argument - illegal ingestion time: 2025-06-18 14:00:00Directly specify a value for the
_partitiondatepseudo-column.INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiondate) VALUES ('beijing_shop',50005.5,DATE '2025-06-15');The following error message is returned:
FAILED: ODPS-0130071:[1,64] Semantic analysis exception - column _partitiondate cannot be resolved; Did you mean _partitiontime ?
Query an ingestion-time partitioned table
When you run a
SELECT *query, the system does not return the_partitiontimeor_partitiondatepseudo-columns or the generated partition key column by default. To display these columns, you must explicitly specify them in the statement, for example,SELECT *, _partitiontime FROM xxx;.For tables partitioned by the hour, month, or year, you can use the
_partitiontimepseudo-column for query filtering and partition pruning. An ingestion-time partitioned table is a special type of auto-partitioned table. It supports the same partition pruning capabilities as a standard auto-partitioned table. For more information, see Auto-partitioned tables based on time functions.
Examples:
The following examples show how to query data from the ingestion_sale_detail_hourly and ingestion_sale_detail_daily tables created in the Examples section.
Example 1
When you run a
SELECT *query, the system does not return the_partitiontimeor_partitiondatepseudo-columns or the generated partition key column by default.SELECT * FROM ingestion_sale_detail_hourly; -- The result is returned. +------------+-------------+ | shop_name | total_price | +---------------+-------------+ | shanghai_shop | 10001.1 | | chongqin_shop | 20002.2 | | hangzhou_shop | 30003.3 | | shenzhen_shop | 40004.4 | | chengdu_shop | 60006.6 | | beijing_shop | 50005.5 | +---------------+-------------+Example 2
You can specify the
_partitiontimeor_partitiondatepseudo-columns and the generated partition key column in your query. In this example,sale_timeandsale_dateare the names of the partition key columns that were specified when the tables were created.NoteIn this example, the project's local time zone is set to `Asia/Shanghai` (UTC+8) by running the
set odps.sql.timezone=Asia/Shanghai;command. The time zone affects the partition values generated by the `TRUNC_TIME` function.Query the
ingestion_sale_detail_hourlytable, which is partitioned by the hour.SELECT * ,_partitiontime,sale_time FROM ingestion_sale_detail_hourly; --The following result is returned: +---------------+-------------+---------------------+---------------------+ | shop_name | total_price | _partitiontime | sale_time | +---------------+-------------+---------------------+---------------------+ | shanghai_shop | 10001.1 | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 | | chongqin_shop | 20002.2 | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 | | hangzhou_shop | 30003.3 | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 | | shenzhen_shop | 40004.4 | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 | | beijing_shop | 50005.5 | 2025-06-15 14:00:00 | 2025-06-15 06:00:00 | | chengdu_shop | 60006.6 | 2025-06-14 05:00:00 | 2025-06-13 21:00:00 | +---------------+-------------+---------------------+---------------------+Query the
ingestion_sale_detail_dailytable, which is partitioned by the day.SELECT * ,_partitiontime,_partitiondate,sale_date FROM ingestion_sale_detail_daily; --The following result is returned: +--------------+-------------+---------------------+----------------+-----------+ | shop_name | total_price | _partitiontime | _partitiondate | sale_date | +--------------+-------------+---------------------+----------------+-----------+ | beijing_shop | 50005.5 | 2025-06-18 00:00:00 | 2025-06-18 | 2025-06-18| +--------------+-------------+---------------------+----------------+-----------+