This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new e52ce1313 refactor(migrations): enhance file meta migration to check
column existence and nullability before modification (#8565)
e52ce1313 is described below
commit e52ce13139c2e30ed0f40efe47ab6fdd239865fb
Author: Bamboo <[email protected]>
AuthorDate: Mon Sep 22 11:10:01 2025 +0800
refactor(migrations): enhance file meta migration to check column existence
and nullability before modification (#8565)
* fix(jira): update epic collector to use new API endpoint and include all
fields
* fix(jira): enhance epic collector to dynamically select API endpoint
based on JIRA version
* fix(jira): update epic collector to use correct API endpoint for JIRA
Cloud and Server versions
* fix(jira): refactor epic collector to streamline API endpoint selection
and enhance error handling
* fix(jira): fix type for Jira issue descriptions
* refactor(jira): update comment and worklog models to use
FlexibleDescription type for comments
* docs(jira): add ADF reference for FlexibleDescription type in issue model
* refactor(migrations): enhance file meta migration to check column
existence and nullability before modification
---
.../migrationscripts/20250320_modify_file_meta.go | 77 ++++++++++++++++++++--
1 file changed, 71 insertions(+), 6 deletions(-)
diff --git
a/backend/plugins/q_dev/models/migrationscripts/20250320_modify_file_meta.go
b/backend/plugins/q_dev/models/migrationscripts/20250320_modify_file_meta.go
index d9d704273..9744f6d09 100644
--- a/backend/plugins/q_dev/models/migrationscripts/20250320_modify_file_meta.go
+++ b/backend/plugins/q_dev/models/migrationscripts/20250320_modify_file_meta.go
@@ -19,6 +19,7 @@ package migrationscripts
import (
"github.com/apache/incubator-devlake/core/context"
+ "github.com/apache/incubator-devlake/core/dal"
"github.com/apache/incubator-devlake/core/errors"
)
@@ -31,14 +32,78 @@ func (*modifyFileMetaTable) Name() string {
func (*modifyFileMetaTable) Up(basicRes context.BasicRes) errors.Error {
db := basicRes.GetDal()
- // 修改 processed_time 列允许为 NULL
- sql := "ALTER TABLE _tool_q_dev_s3_file_meta MODIFY processed_time
DATETIME NULL"
- err := db.Exec(sql)
- if err != nil {
- return errors.Default.Wrap(err, "failed to modify
processed_time column")
+ // Target table and column
+ tableName := "_tool_q_dev_s3_file_meta"
+ columnName := "processed_time"
+
+ // If column doesn't exist, no migration needed, idempotent
+ if !db.HasColumn(tableName, columnName) {
+ return nil
}
- return nil
+ // Read column metadata to check if already nullable, return
idempotently if already nullable
+ var processedTimeNullable bool
+ {
+ cols, err := db.GetColumns(dal.DefaultTabler{Name: tableName},
func(cm dal.ColumnMeta) bool {
+ return cm.Name() == columnName
+ })
+ if err != nil {
+ return errors.Default.Wrap(err, "failed to load column
metadata for _tool_q_dev_s3_file_meta.processed_time")
+ }
+ if len(cols) == 0 {
+ // If column is not visible in metadata, treat as no
processing needed
+ return nil
+ }
+ if nullable, ok := cols[0].Nullable(); ok {
+ processedTimeNullable = nullable
+ }
+ }
+ if processedTimeNullable {
+ return nil
+ }
+
+ // Execute compatible SQL by dialect
+ switch db.Dialect() {
+ case "postgres":
+ // PostgreSQL makes column nullable via DROP NOT NULL, without
changing data type
+ if err := db.Exec(
+ "ALTER TABLE ? ALTER COLUMN ? DROP NOT NULL",
+ dal.ClauseTable{Name: tableName},
+ dal.ClauseColumn{Name: columnName},
+ ); err != nil {
+ return errors.Default.Wrap(err, "failed to drop NOT
NULL on processed_time for postgres")
+ }
+ return nil
+ case "mysql":
+ // MySQL requires MODIFY COLUMN with original type
specification, preserve original type as much as possible
+ cols, err := db.GetColumns(dal.DefaultTabler{Name: tableName},
func(cm dal.ColumnMeta) bool {
+ return cm.Name() == columnName
+ })
+ if err != nil {
+ return errors.Default.Wrap(err, "failed to load column
metadata for mysql type preservation")
+ }
+ columnTypeSql := "DATETIME"
+ if len(cols) > 0 {
+ if ct, ok := cols[0].ColumnType(); ok && ct != "" {
+ columnTypeSql = ct
+ } else if dbt := cols[0].DatabaseTypeName(); dbt != "" {
+ // DatabaseTypeName may return DATETIME,
TIMESTAMP etc
+ columnTypeSql = dbt
+ }
+ }
+ alterSql := "ALTER TABLE ? MODIFY COLUMN ? " + columnTypeSql +
" NULL"
+ if err := db.Exec(
+ alterSql,
+ dal.ClauseTable{Name: tableName},
+ dal.ClauseColumn{Name: columnName},
+ ); err != nil {
+ return errors.Default.Wrap(err, "failed to modify
processed_time to NULL for mysql")
+ }
+ return nil
+ default:
+ // Other dialects are not forced to migrate for now, return
idempotently
+ return nil
+ }
}
func (*modifyFileMetaTable) Version() uint64 {