[BUG] Sort m2m fields before comparing them with diff(...)
(#271)
* 🐛 Sort m2m fields before comparing them with `diff(...)`
* Add test case and upgrade changelog
---------
Co-authored-by: Waket Zheng <waketzheng@gmail.com>
This commit is contained in:
parent
44025823ee
commit
8cefe68c9b
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
## 0.8
|
## 0.8
|
||||||
|
|
||||||
|
### [0.8.1](Unreleased)
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
- Sort m2m fields before comparing them with diff. (#271)
|
||||||
|
|
||||||
### [0.8.0](../../releases/tag/v0.8.0) - 2024-12-04
|
### [0.8.0](../../releases/tag/v0.8.0) - 2024-12-04
|
||||||
|
|
||||||
- Fix the issue of parameter concatenation when generating ORM with inspectdb (#331)
|
- Fix the issue of parameter concatenation when generating ORM with inspectdb (#331)
|
||||||
|
@ -271,6 +271,10 @@ class Migrate:
|
|||||||
# m2m fields
|
# m2m fields
|
||||||
old_m2m_fields = cast(List[dict], old_model_describe.get("m2m_fields"))
|
old_m2m_fields = cast(List[dict], old_model_describe.get("m2m_fields"))
|
||||||
new_m2m_fields = cast(List[dict], new_model_describe.get("m2m_fields"))
|
new_m2m_fields = cast(List[dict], new_model_describe.get("m2m_fields"))
|
||||||
|
if old_m2m_fields and len(new_m2m_fields) >= 2:
|
||||||
|
length = len(old_m2m_fields)
|
||||||
|
field_index = {f["name"]: i for i, f in enumerate(new_m2m_fields)}
|
||||||
|
new_m2m_fields.sort(key=lambda field: field_index.get(field["name"], length))
|
||||||
for action, _, change in diff(old_m2m_fields, new_m2m_fields):
|
for action, _, change in diff(old_m2m_fields, new_m2m_fields):
|
||||||
if change[0][0] == "db_constraint":
|
if change[0][0] == "db_constraint":
|
||||||
continue
|
continue
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "aerich"
|
name = "aerich"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
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"
|
||||||
|
@ -31,6 +31,8 @@ class User(Model):
|
|||||||
intro = fields.TextField(default="")
|
intro = fields.TextField(default="")
|
||||||
longitude = fields.DecimalField(max_digits=10, decimal_places=8)
|
longitude = fields.DecimalField(max_digits=10, decimal_places=8)
|
||||||
|
|
||||||
|
products: fields.ManyToManyRelation["Product"]
|
||||||
|
|
||||||
|
|
||||||
class Email(Model):
|
class Email(Model):
|
||||||
email_id = fields.IntField(primary_key=True)
|
email_id = fields.IntField(primary_key=True)
|
||||||
@ -56,6 +58,9 @@ class Category(Model):
|
|||||||
|
|
||||||
class Product(Model):
|
class Product(Model):
|
||||||
categories: fields.ManyToManyRelation[Category] = fields.ManyToManyField("models.Category")
|
categories: fields.ManyToManyRelation[Category] = fields.ManyToManyField("models.Category")
|
||||||
|
users: fields.ManyToManyRelation[User] = fields.ManyToManyField(
|
||||||
|
"models.User", related_name="products"
|
||||||
|
)
|
||||||
name = fields.CharField(max_length=50)
|
name = fields.CharField(max_length=50)
|
||||||
view_num = fields.IntField(description="View Num", default=0)
|
view_num = fields.IntField(description="View Num", default=0)
|
||||||
sort = fields.IntField()
|
sort = fields.IntField()
|
||||||
|
@ -846,6 +846,7 @@ def test_migrate(mocker: MockerFixture):
|
|||||||
- add unique: User.username
|
- add unique: User.username
|
||||||
- change column: length User.password
|
- change column: length User.password
|
||||||
- add unique_together: (name,type) of Product
|
- add unique_together: (name,type) of Product
|
||||||
|
- add one more many to many field: Product.users
|
||||||
- drop unique field: Config.name
|
- drop unique field: Config.name
|
||||||
- alter default: Config.status
|
- alter default: Config.status
|
||||||
- rename column: Product.image -> Product.pic
|
- rename column: Product.image -> Product.pic
|
||||||
@ -902,6 +903,7 @@ def test_migrate(mocker: MockerFixture):
|
|||||||
"ALTER TABLE `category` MODIFY COLUMN `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)",
|
"ALTER TABLE `category` MODIFY COLUMN `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)",
|
||||||
"ALTER TABLE `product` MODIFY COLUMN `body` LONGTEXT NOT NULL",
|
"ALTER TABLE `product` MODIFY COLUMN `body` LONGTEXT NOT NULL",
|
||||||
"ALTER TABLE `email` MODIFY COLUMN `is_primary` BOOL NOT NULL DEFAULT 0",
|
"ALTER TABLE `email` MODIFY COLUMN `is_primary` BOOL NOT NULL DEFAULT 0",
|
||||||
|
"CREATE TABLE `product_user` (\n `product_id` INT NOT NULL REFERENCES `product` (`id`) ON DELETE CASCADE,\n `user_id` INT NOT NULL REFERENCES `user` (`id`) ON DELETE CASCADE\n) CHARACTER SET utf8mb4",
|
||||||
}
|
}
|
||||||
expected_downgrade_operators = {
|
expected_downgrade_operators = {
|
||||||
"ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200) NOT NULL",
|
"ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200) NOT NULL",
|
||||||
@ -928,6 +930,7 @@ def test_migrate(mocker: MockerFixture):
|
|||||||
"ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(200) NOT NULL",
|
"ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(200) NOT NULL",
|
||||||
"DROP TABLE IF EXISTS `email_user`",
|
"DROP TABLE IF EXISTS `email_user`",
|
||||||
"DROP TABLE IF EXISTS `newmodel`",
|
"DROP TABLE IF EXISTS `newmodel`",
|
||||||
|
"DROP TABLE IF EXISTS `product_user`",
|
||||||
"ALTER TABLE `user` MODIFY COLUMN `intro` LONGTEXT NOT NULL",
|
"ALTER TABLE `user` MODIFY COLUMN `intro` LONGTEXT NOT NULL",
|
||||||
"ALTER TABLE `config` MODIFY COLUMN `value` TEXT NOT NULL",
|
"ALTER TABLE `config` MODIFY COLUMN `value` TEXT NOT NULL",
|
||||||
"ALTER TABLE `category` MODIFY COLUMN `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)",
|
"ALTER TABLE `category` MODIFY COLUMN `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)",
|
||||||
@ -987,6 +990,7 @@ def test_migrate(mocker: MockerFixture):
|
|||||||
'CREATE TABLE IF NOT EXISTS "newmodel" (\n "id" SERIAL NOT NULL PRIMARY KEY,\n "name" VARCHAR(50) NOT NULL\n);\nCOMMENT ON COLUMN "config"."user_id" IS \'User\'',
|
'CREATE TABLE IF NOT EXISTS "newmodel" (\n "id" SERIAL NOT NULL PRIMARY KEY,\n "name" VARCHAR(50) NOT NULL\n);\nCOMMENT ON COLUMN "config"."user_id" IS \'User\'',
|
||||||
'CREATE UNIQUE INDEX "uid_product_name_869427" ON "product" ("name", "type_db_alias")',
|
'CREATE UNIQUE INDEX "uid_product_name_869427" ON "product" ("name", "type_db_alias")',
|
||||||
'CREATE UNIQUE INDEX "uid_user_usernam_9987ab" ON "user" ("username")',
|
'CREATE UNIQUE INDEX "uid_user_usernam_9987ab" ON "user" ("username")',
|
||||||
|
'CREATE TABLE "product_user" (\n "product_id" INT NOT NULL REFERENCES "product" ("id") ON DELETE CASCADE,\n "user_id" INT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE\n)',
|
||||||
}
|
}
|
||||||
expected_downgrade_operators = {
|
expected_downgrade_operators = {
|
||||||
'CREATE UNIQUE INDEX "uid_category_title_f7fc03" ON "category" ("title")',
|
'CREATE UNIQUE INDEX "uid_category_title_f7fc03" ON "category" ("title")',
|
||||||
@ -1018,6 +1022,7 @@ def test_migrate(mocker: MockerFixture):
|
|||||||
'ALTER TABLE "product" ALTER COLUMN "created_at" TYPE TIMESTAMPTZ USING "created_at"::TIMESTAMPTZ',
|
'ALTER TABLE "product" ALTER COLUMN "created_at" TYPE TIMESTAMPTZ USING "created_at"::TIMESTAMPTZ',
|
||||||
'ALTER TABLE "product" ALTER COLUMN "is_reviewed" TYPE BOOL USING "is_reviewed"::BOOL',
|
'ALTER TABLE "product" ALTER COLUMN "is_reviewed" TYPE BOOL USING "is_reviewed"::BOOL',
|
||||||
'ALTER TABLE "product" ALTER COLUMN "body" TYPE TEXT USING "body"::TEXT',
|
'ALTER TABLE "product" ALTER COLUMN "body" TYPE TEXT USING "body"::TEXT',
|
||||||
|
'DROP TABLE IF EXISTS "product_user"',
|
||||||
'DROP INDEX "idx_product_name_869427"',
|
'DROP INDEX "idx_product_name_869427"',
|
||||||
'DROP INDEX "idx_email_email_4a1a33"',
|
'DROP INDEX "idx_email_email_4a1a33"',
|
||||||
'DROP INDEX "uid_user_usernam_9987ab"',
|
'DROP INDEX "uid_user_usernam_9987ab"',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user