@@ -309,6 +309,28 @@ func (m Migrator) AlterColumn(value interface{}, field string) error {
309309 return m .RunWithValue (value , func (stmt * gorm.Statement ) error {
310310 if stmt .Schema != nil {
311311 if field := stmt .Schema .LookUpField (field ); field != nil {
312+ columnTypes , err := m .ColumnTypes (value )
313+ if err == nil {
314+ for _ , col := range columnTypes {
315+ if strings .EqualFold (col .Name (), field .DBName ) {
316+ currentNullable , _ := col .Nullable ()
317+ desiredNullable := ! field .NotNull
318+
319+ // Skip if nullability is unchanged
320+ if currentNullable == desiredNullable {
321+ return nil
322+ }
323+
324+ // Skip if trying to make nullable → non-nullable
325+ if currentNullable && ! desiredNullable {
326+ return nil
327+ }
328+
329+ // Only case left: non-nullable → nullable → allowed
330+ break
331+ }
332+ }
333+ }
312334 fileType := m .FullDataTypeOf (field )
313335 return m .DB .Exec (
314336 "ALTER TABLE ? MODIFY ? ?" ,
@@ -448,9 +470,13 @@ func (m Migrator) FullDataTypeOf(field *schema.Field) (expr clause.Expr) {
448470 }
449471 }
450472
451- // Add NOT NULL after defaults
452- if field .NotNull {
453- expr .SQL += " NOT NULL"
473+ // Skip NULL/NOT NULL for identity columns
474+ if ! strings .Contains (strings .ToUpper (expr .SQL ), "IDENTITY" ) {
475+ if field .NotNull {
476+ expr .SQL += " NOT NULL"
477+ } else {
478+ expr .SQL += " NULL"
479+ }
454480 }
455481
456482 return expr
0 commit comments