update
This commit is contained in:
parent
b4cc2de0e3
commit
36f84702b7
@ -1 +1 @@
|
|||||||
__version__ = "0.4.5"
|
__version__ = "0.5.0"
|
||||||
|
@ -84,25 +84,27 @@ class BaseDDL:
|
|||||||
default = ""
|
default = ""
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def add_column(self, model: "Type[Model]", field_object: Field):
|
def add_column(self, model: "Type[Model]", field_describe: dict, is_pk: bool = False):
|
||||||
db_table = model._meta.db_table
|
db_table = model._meta.db_table
|
||||||
|
description = field_describe.get("description")
|
||||||
|
db_column = field_describe.get("db_column")
|
||||||
|
db_field_types = field_describe.get("db_field_types")
|
||||||
return self._ADD_COLUMN_TEMPLATE.format(
|
return self._ADD_COLUMN_TEMPLATE.format(
|
||||||
table_name=db_table,
|
table_name=db_table,
|
||||||
column=self.schema_generator._create_string(
|
column=self.schema_generator._create_string(
|
||||||
db_column=field_object.model_field_name,
|
db_column=db_column,
|
||||||
field_type=field_object.get_for_dialect(self.DIALECT, "SQL_TYPE"),
|
field_type=db_field_types.get(self.DIALECT, db_field_types.get("")),
|
||||||
nullable="NOT NULL" if not field_object.null else "",
|
nullable="NOT NULL" if not field_describe.get("nullable") else "",
|
||||||
unique="UNIQUE" if field_object.unique else "",
|
unique="UNIQUE" if field_describe.get("unique") else "",
|
||||||
comment=self.schema_generator._column_comment_generator(
|
comment=self.schema_generator._column_comment_generator(
|
||||||
table=db_table,
|
table=db_table,
|
||||||
column=field_object.model_field_name,
|
column=db_column,
|
||||||
comment=field_object.description,
|
comment=field_describe.get("description"),
|
||||||
)
|
)
|
||||||
if field_object.description
|
if description
|
||||||
else "",
|
else "",
|
||||||
is_primary_key=field_object.pk,
|
is_primary_key=is_pk,
|
||||||
default=self._get_default(model, field_object),
|
default=field_describe.get("default"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -140,7 +142,7 @@ class BaseDDL:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def change_column(
|
def change_column(
|
||||||
self, model: "Type[Model]", old_column_name: str, new_column_name: str, new_column_type: str
|
self, model: "Type[Model]", old_column_name: str, new_column_name: str, new_column_type: str
|
||||||
):
|
):
|
||||||
return self._CHANGE_COLUMN_TEMPLATE.format(
|
return self._CHANGE_COLUMN_TEMPLATE.format(
|
||||||
table_name=model._meta.db_table,
|
table_name=model._meta.db_table,
|
||||||
@ -170,7 +172,7 @@ class BaseDDL:
|
|||||||
def add_fk(self, model: "Type[Model]", field: dict):
|
def add_fk(self, model: "Type[Model]", field: dict):
|
||||||
db_table = model._meta.db_table
|
db_table = model._meta.db_table
|
||||||
|
|
||||||
db_column = field.get('db_column')
|
db_column = field.get("db_column")
|
||||||
fk_name = self.schema_generator._generate_fk_name(
|
fk_name = self.schema_generator._generate_fk_name(
|
||||||
from_table=db_table,
|
from_table=db_table,
|
||||||
from_field=db_column,
|
from_field=db_column,
|
||||||
@ -183,7 +185,7 @@ class BaseDDL:
|
|||||||
db_column=db_column,
|
db_column=db_column,
|
||||||
table=field.related_model._meta.db_table,
|
table=field.related_model._meta.db_table,
|
||||||
field=db_column,
|
field=db_column,
|
||||||
on_delete=field.get('on_delete'),
|
on_delete=field.get("on_delete"),
|
||||||
)
|
)
|
||||||
|
|
||||||
def drop_fk(self, model: "Type[Model]", field: ForeignKeyFieldInstance):
|
def drop_fk(self, model: "Type[Model]", field: ForeignKeyFieldInstance):
|
||||||
|
@ -3,7 +3,6 @@ from datetime import datetime
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Tuple, Type
|
from typing import Dict, List, Optional, Tuple, Type
|
||||||
|
|
||||||
import click
|
|
||||||
from dictdiffer import diff
|
from dictdiffer import diff
|
||||||
from tortoise import (
|
from tortoise import (
|
||||||
BackwardFKRelation,
|
BackwardFKRelation,
|
||||||
@ -162,9 +161,7 @@ class Migrate:
|
|||||||
cls.downgrade_operators.append(operator)
|
cls.downgrade_operators.append(operator)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def diff_models(
|
def diff_models(cls, old_models: Dict[str, dict], new_models: Dict[str, dict], upgrade=True):
|
||||||
cls, old_models: Dict[str, dict], new_models: Dict[str, dict], upgrade=True
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
diff models and add operators
|
diff models and add operators
|
||||||
:param old_models:
|
:param old_models:
|
||||||
@ -172,7 +169,7 @@ class Migrate:
|
|||||||
:param upgrade:
|
:param upgrade:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
_aerich = f'{cls.app}.{cls._aerich}'
|
_aerich = f"{cls.app}.{cls._aerich}"
|
||||||
old_models.pop(_aerich, None)
|
old_models.pop(_aerich, None)
|
||||||
new_models.pop(_aerich, None)
|
new_models.pop(_aerich, None)
|
||||||
|
|
||||||
@ -209,10 +206,28 @@ class Migrate:
|
|||||||
"""
|
"""
|
||||||
for change in diff(old_model_describe, new_model_describe):
|
for change in diff(old_model_describe, new_model_describe):
|
||||||
action, field_type, fields = change
|
action, field_type, fields = change
|
||||||
if action == 'add':
|
is_pk = field_type == "pk_field"
|
||||||
|
if action == "add":
|
||||||
for field in fields:
|
for field in fields:
|
||||||
_, field_describe = field
|
_, field_describe = field
|
||||||
cls._add_field(cls._get_model)
|
cls._add_operator(
|
||||||
|
cls._add_field(
|
||||||
|
cls._get_model(new_model_describe.get("name").split(".")[1]),
|
||||||
|
field_describe,
|
||||||
|
is_pk,
|
||||||
|
),
|
||||||
|
upgrade,
|
||||||
|
)
|
||||||
|
elif action == "remove":
|
||||||
|
for field in fields:
|
||||||
|
_, field_describe = field
|
||||||
|
cls._add_operator(
|
||||||
|
cls._remove_field(
|
||||||
|
cls._get_model(new_model_describe.get("name").split(".")[1]),
|
||||||
|
field_describe,
|
||||||
|
),
|
||||||
|
upgrade,
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _resolve_fk_fields_name(cls, model: Type[Model], fields_name: Tuple[str]):
|
def _resolve_fk_fields_name(cls, model: Type[Model], fields_name: Tuple[str]):
|
||||||
@ -258,12 +273,12 @@ class Migrate:
|
|||||||
return isinstance(field, (BackwardFKRelation, BackwardOneToOneRelation))
|
return isinstance(field, (BackwardFKRelation, BackwardOneToOneRelation))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _add_field(cls, model: Type[Model], field: dict):
|
def _add_field(cls, model: Type[Model], field: dict, is_pk: bool = False):
|
||||||
if field.get('field_type') == 'ForeignKeyFieldInstance':
|
if field.get("field_type") == "ForeignKeyFieldInstance":
|
||||||
return cls.ddl.add_fk(model, field)
|
return cls.ddl.add_fk(model, field)
|
||||||
if field.get('field_type') == 'ManyToManyFieldInstance':
|
if field.get("field_type") == "ManyToManyFieldInstance":
|
||||||
return cls.ddl.create_m2m_table(model, field)
|
return cls.ddl.create_m2m_table(model, field)
|
||||||
return cls.ddl.add_column(model, field)
|
return cls.ddl.add_column(model, field, is_pk)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _alter_default(cls, model: Type[Model], field: Field):
|
def _alter_default(cls, model: Type[Model], field: Field):
|
||||||
|
@ -51,12 +51,6 @@ def event_loop():
|
|||||||
|
|
||||||
@pytest.fixture(scope="session", autouse=True)
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
async def initialize_tests(event_loop, request):
|
async def initialize_tests(event_loop, request):
|
||||||
tortoise_orm["connections"]["diff_models"] = "sqlite://:memory:"
|
|
||||||
tortoise_orm["apps"]["diff_models"] = {
|
|
||||||
"models": ["tests.diff_models"],
|
|
||||||
"default_connection": "diff_models",
|
|
||||||
}
|
|
||||||
|
|
||||||
await Tortoise.init(config=tortoise_orm, _create_db=True)
|
await Tortoise.init(config=tortoise_orm, _create_db=True)
|
||||||
await generate_schema_for_client(Tortoise.get_connection("default"), safe=True)
|
await generate_schema_for_client(Tortoise.get_connection("default"), safe=True)
|
||||||
|
|
||||||
|
28
poetry.lock
generated
28
poetry.lock
generated
@ -138,6 +138,20 @@ python-versions = "*"
|
|||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pyparsing = "*"
|
pyparsing = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dictdiffer"
|
||||||
|
version = "0.8.1"
|
||||||
|
description = "Dictdiffer is a library that helps you to diff and patch dictionaries."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
all = ["Sphinx (>=1.4.4)", "sphinx-rtd-theme (>=0.1.9)", "check-manifest (>=0.25)", "coverage (>=4.0)", "isort (>=4.2.2)", "mock (>=1.3.0)", "pydocstyle (>=1.0.0)", "pytest-cov (>=1.8.0)", "pytest-pep8 (>=1.0.6)", "pytest (>=2.8.0)", "tox (>=3.7.0)", "numpy (>=1.11.0)"]
|
||||||
|
docs = ["Sphinx (>=1.4.4)", "sphinx-rtd-theme (>=0.1.9)"]
|
||||||
|
numpy = ["numpy (>=1.11.0)"]
|
||||||
|
tests = ["check-manifest (>=0.25)", "coverage (>=4.0)", "isort (>=4.2.2)", "mock (>=1.3.0)", "pydocstyle (>=1.0.0)", "pytest-cov (>=1.8.0)", "pytest-pep8 (>=1.0.6)", "pytest (>=2.8.0)", "tox (>=3.7.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "execnet"
|
name = "execnet"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
@ -251,7 +265,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "20.8"
|
version = "20.9"
|
||||||
description = "Core utilities for Python packages"
|
description = "Core utilities for Python packages"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@ -547,7 +561,7 @@ dbdrivers = ["aiomysql", "asyncpg"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
content-hash = "9adf7beba99d615c71a9148391386c9016cbafc7c11c5fc3ad81c8ec61026236"
|
content-hash = "f4ef33a953946570d6d35a479dad75768cd3c6a72e5953c68f2de1566c40873b"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiomysql = [
|
aiomysql = [
|
||||||
@ -614,12 +628,15 @@ click = [
|
|||||||
]
|
]
|
||||||
colorama = [
|
colorama = [
|
||||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
|
||||||
]
|
]
|
||||||
ddlparse = [
|
ddlparse = [
|
||||||
{file = "ddlparse-1.9.0-py3-none-any.whl", hash = "sha256:a7962615a9325be7d0f182cbe34011e6283996473fb98c784c6f675b9783bc18"},
|
{file = "ddlparse-1.9.0-py3-none-any.whl", hash = "sha256:a7962615a9325be7d0f182cbe34011e6283996473fb98c784c6f675b9783bc18"},
|
||||||
{file = "ddlparse-1.9.0.tar.gz", hash = "sha256:cdffcf2f692f304a23c8e903b00afd7e83a920b79a2ff4e2f25c875b369d4f58"},
|
{file = "ddlparse-1.9.0.tar.gz", hash = "sha256:cdffcf2f692f304a23c8e903b00afd7e83a920b79a2ff4e2f25c875b369d4f58"},
|
||||||
]
|
]
|
||||||
|
dictdiffer = [
|
||||||
|
{file = "dictdiffer-0.8.1-py2.py3-none-any.whl", hash = "sha256:d79d9a39e459fe33497c858470ca0d2e93cb96621751de06d631856adfd9c390"},
|
||||||
|
{file = "dictdiffer-0.8.1.tar.gz", hash = "sha256:1adec0d67cdf6166bda96ae2934ddb5e54433998ceab63c984574d187cc563d2"},
|
||||||
|
]
|
||||||
execnet = [
|
execnet = [
|
||||||
{file = "execnet-1.8.0-py2.py3-none-any.whl", hash = "sha256:7a13113028b1e1cc4c6492b28098b3c6576c9dccc7973bfe47b342afadafb2ac"},
|
{file = "execnet-1.8.0-py2.py3-none-any.whl", hash = "sha256:7a13113028b1e1cc4c6492b28098b3c6576c9dccc7973bfe47b342afadafb2ac"},
|
||||||
{file = "execnet-1.8.0.tar.gz", hash = "sha256:b73c5565e517f24b62dea8a5ceac178c661c4309d3aa0c3e420856c072c411b4"},
|
{file = "execnet-1.8.0.tar.gz", hash = "sha256:b73c5565e517f24b62dea8a5ceac178c661c4309d3aa0c3e420856c072c411b4"},
|
||||||
@ -641,7 +658,6 @@ importlib-metadata = [
|
|||||||
{file = "importlib_metadata-3.4.0.tar.gz", hash = "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d"},
|
{file = "importlib_metadata-3.4.0.tar.gz", hash = "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d"},
|
||||||
]
|
]
|
||||||
iniconfig = [
|
iniconfig = [
|
||||||
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
|
||||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||||
]
|
]
|
||||||
iso8601 = [
|
iso8601 = [
|
||||||
@ -662,8 +678,8 @@ mypy-extensions = [
|
|||||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||||
]
|
]
|
||||||
packaging = [
|
packaging = [
|
||||||
{file = "packaging-20.8-py2.py3-none-any.whl", hash = "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858"},
|
{file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"},
|
||||||
{file = "packaging-20.8.tar.gz", hash = "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093"},
|
{file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"},
|
||||||
]
|
]
|
||||||
pathspec = [
|
pathspec = [
|
||||||
{file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
|
{file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "aerich"
|
name = "aerich"
|
||||||
version = "0.4.5"
|
version = "0.5.0"
|
||||||
description = "A database migrations tool for Tortoise ORM."
|
description = "A database migrations tool for Tortoise ORM."
|
||||||
authors = ["long2ice <long2ice@gmail.com>"]
|
authors = ["long2ice <long2ice@gmail.com>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
@ -22,6 +22,7 @@ pydantic = "*"
|
|||||||
aiomysql = {version = "*", optional = true}
|
aiomysql = {version = "*", optional = true}
|
||||||
asyncpg = {version = "*", optional = true}
|
asyncpg = {version = "*", optional = true}
|
||||||
ddlparse = "*"
|
ddlparse = "*"
|
||||||
|
dictdiffer = "*"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
flake8 = "*"
|
flake8 = "*"
|
||||||
|
@ -28,7 +28,6 @@ class User(Model):
|
|||||||
is_active = fields.BooleanField(default=True, description="Is Active")
|
is_active = fields.BooleanField(default=True, description="Is Active")
|
||||||
is_superuser = fields.BooleanField(default=False, description="Is SuperUser")
|
is_superuser = fields.BooleanField(default=False, description="Is SuperUser")
|
||||||
avatar = fields.CharField(max_length=200, default="")
|
avatar = fields.CharField(max_length=200, default="")
|
||||||
intro = fields.TextField(default="")
|
|
||||||
|
|
||||||
|
|
||||||
class Email(Model):
|
class Email(Model):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user