diff --git a/.gitignore b/.gitignore index 81065c9..3a0dd29 100644 --- a/.gitignore +++ b/.gitignore @@ -146,3 +146,4 @@ aerich.ini src .vscode .DS_Store +.python-version \ No newline at end of file diff --git a/aerich/ddl/__init__.py b/aerich/ddl/__init__.py index 7e7740c..d861406 100644 --- a/aerich/ddl/__init__.py +++ b/aerich/ddl/__init__.py @@ -4,6 +4,8 @@ from typing import List, Type from tortoise import BaseDBAsyncClient, Model from tortoise.backends.base.schema_generator import BaseSchemaGenerator +from aerich.utils import is_default_function + class BaseDDL: schema_generator_cls: Type[BaseSchemaGenerator] = BaseSchemaGenerator @@ -76,7 +78,7 @@ class BaseDDL: auto_now_add = field_describe.get("auto_now_add", False) auto_now = field_describe.get("auto_now", False) if default is not None or auto_now_add: - if field_describe.get("field_type") in ["UUIDField", "TextField", "JSONField"]: + if field_describe.get("field_type") in ["UUIDField", "TextField", "JSONField"] or is_default_function(default): default = "" else: try: diff --git a/aerich/migrate.py b/aerich/migrate.py index e8ec20d..e21e340 100644 --- a/aerich/migrate.py +++ b/aerich/migrate.py @@ -1,4 +1,5 @@ import os +import re from datetime import datetime from pathlib import Path from typing import Dict, List, Optional, Tuple, Type @@ -10,7 +11,12 @@ from tortoise.exceptions import OperationalError from aerich.ddl import BaseDDL from aerich.models import MAX_VERSION_LENGTH, Aerich -from aerich.utils import get_app_connection, get_models_describe, write_version_file +from aerich.utils import ( + get_app_connection, + get_models_describe, + is_default_function, + write_version_file, +) class Migrate: @@ -394,8 +400,13 @@ class Migrate: # continue since repeated with others continue elif option == "default": - # change column default - cls._add_operator(cls._alter_default(model, new_data_field), upgrade) + if not ( + is_default_function(old_new[0]) or is_default_function(old_new[1]) + ): + # change column default + cls._add_operator( + cls._alter_default(model, new_data_field), upgrade + ) elif option == "unique": # because indexed include it pass diff --git a/aerich/utils.py b/aerich/utils.py index 6e12716..5ce87da 100644 --- a/aerich/utils.py +++ b/aerich/utils.py @@ -1,4 +1,5 @@ import importlib +import re from typing import Dict from click import BadOptionUsage, Context @@ -121,3 +122,7 @@ def get_models_describe(app: str) -> Dict: describe = model.describe() ret[describe.get("name")] = describe return ret + + +def is_default_function(string: str): + return re.match(r"^$", str(string or "")) diff --git a/tests/models.py b/tests/models.py index 80301a4..e09dd65 100644 --- a/tests/models.py +++ b/tests/models.py @@ -1,4 +1,5 @@ import datetime +import uuid from enum import IntEnum from tortoise import Model, fields @@ -38,9 +39,13 @@ class Email(Model): users = fields.ManyToManyField("models.User") +def default_name(): + return uuid.uuid4() + + class Category(Model): slug = fields.CharField(max_length=100) - name = fields.CharField(max_length=200, null=True) + name = fields.CharField(max_length=200, null=True, default=default_name) user = fields.ForeignKeyField("models.User", description="User") created_at = fields.DatetimeField(auto_now_add=True)