Fix postgres field type change error. (#135)
This commit is contained in:
		| @@ -5,6 +5,7 @@ | |||||||
| ### 0.5.2 | ### 0.5.2 | ||||||
|  |  | ||||||
| - Fix rename field on the field add. (#134) | - Fix rename field on the field add. (#134) | ||||||
|  | - Fix postgres field type change error. (#135) | ||||||
|  |  | ||||||
| ### 0.5.1 | ### 0.5.1 | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								README.md
									
									
									
									
									
								
							| @@ -8,11 +8,7 @@ | |||||||
| ## Introduction | ## Introduction | ||||||
|  |  | ||||||
| Aerich is a database migrations tool for Tortoise-ORM, which is like alembic for SQLAlchemy, or like Django ORM with | Aerich is a database migrations tool for Tortoise-ORM, which is like alembic for SQLAlchemy, or like Django ORM with | ||||||
| it\'s own migrations solution. | it\'s own migration solution. | ||||||
|  |  | ||||||
| ~~**Important: You can only use absolutely import in your `models.py` to make `aerich` work.**~~ |  | ||||||
|  |  | ||||||
| From version `v0.5.0`, there is no such limitation now. |  | ||||||
|  |  | ||||||
| ## Install | ## Install | ||||||
|  |  | ||||||
| @@ -97,8 +93,8 @@ Success create app migrate location ./migrations/models | |||||||
| Success generate schema for app "models" | Success generate schema for app "models" | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| If your Tortoise-ORM app is not the default `models`, you must specify the correct app via `--app`, e.g. `aerich | If your Tortoise-ORM app is not the default `models`, you must specify the correct app via `--app`, | ||||||
| --app other_models init-db`. | e.g. `aerich --app other_models init-db`. | ||||||
|  |  | ||||||
| ### Update models and make migrate | ### Update models and make migrate | ||||||
|  |  | ||||||
| @@ -193,8 +189,7 @@ Inspect a specified table in the default app and redirect to `models.py`: | |||||||
| aerich inspectdb -t user > models.py | aerich inspectdb -t user > models.py | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Note that this command is limited and cannot infer some fields, such as `IntEnumField`, `ForeignKeyField`, and | Note that this command is limited and cannot infer some fields, such as `IntEnumField`, `ForeignKeyField`, and others. | ||||||
| others. |  | ||||||
|  |  | ||||||
| ### Multiple databases | ### Multiple databases | ||||||
|  |  | ||||||
| @@ -213,12 +208,6 @@ tortoise_orm = { | |||||||
|  |  | ||||||
| You only need to specify `aerich.models` in one app, and must specify `--app` when running `aerich migrate` and so on. | You only need to specify `aerich.models` in one app, and must specify `--app` when running `aerich migrate` and so on. | ||||||
|  |  | ||||||
| ## Support this project |  | ||||||
|  |  | ||||||
| | AliPay                                                                                 | WeChatPay                                                                                 | PayPal                                                           | |  | ||||||
| | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | |  | ||||||
| | <img width="200" src="https://github.com/long2ice/aerich/raw/dev/images/alipay.jpeg"/> | <img width="200" src="https://github.com/long2ice/aerich/raw/dev/images/wechatpay.jpeg"/> | [PayPal](https://www.paypal.me/long2ice) to my account long2ice. | |  | ||||||
|  |  | ||||||
| ## License | ## License | ||||||
|  |  | ||||||
| This project is licensed under the | This project is licensed under the | ||||||
|   | |||||||
| @@ -12,7 +12,9 @@ class PostgresDDL(BaseDDL): | |||||||
|     _ADD_INDEX_TEMPLATE = 'CREATE {unique}INDEX "{index_name}" ON "{table_name}" ({column_names})' |     _ADD_INDEX_TEMPLATE = 'CREATE {unique}INDEX "{index_name}" ON "{table_name}" ({column_names})' | ||||||
|     _DROP_INDEX_TEMPLATE = 'DROP INDEX "{index_name}"' |     _DROP_INDEX_TEMPLATE = 'DROP INDEX "{index_name}"' | ||||||
|     _ALTER_NULL_TEMPLATE = 'ALTER TABLE "{table_name}" ALTER COLUMN "{column}" {set_drop} NOT NULL' |     _ALTER_NULL_TEMPLATE = 'ALTER TABLE "{table_name}" ALTER COLUMN "{column}" {set_drop} NOT NULL' | ||||||
|     _MODIFY_COLUMN_TEMPLATE = 'ALTER TABLE "{table_name}" ALTER COLUMN "{column}" TYPE {datatype}' |     _MODIFY_COLUMN_TEMPLATE = ( | ||||||
|  |         'ALTER TABLE "{table_name}" ALTER COLUMN "{column}" TYPE {datatype}{using}' | ||||||
|  |     ) | ||||||
|     _SET_COMMENT_TEMPLATE = 'COMMENT ON COLUMN "{table_name}"."{column}" IS {comment}' |     _SET_COMMENT_TEMPLATE = 'COMMENT ON COLUMN "{table_name}"."{column}" IS {comment}' | ||||||
|     _DROP_FK_TEMPLATE = 'ALTER TABLE "{table_name}" DROP CONSTRAINT "{fk_name}"' |     _DROP_FK_TEMPLATE = 'ALTER TABLE "{table_name}" DROP CONSTRAINT "{fk_name}"' | ||||||
|  |  | ||||||
| @@ -27,10 +29,13 @@ class PostgresDDL(BaseDDL): | |||||||
|     def modify_column(self, model: "Type[Model]", field_describe: dict, is_pk: bool = False): |     def modify_column(self, model: "Type[Model]", field_describe: dict, is_pk: bool = False): | ||||||
|         db_table = model._meta.db_table |         db_table = model._meta.db_table | ||||||
|         db_field_types = field_describe.get("db_field_types") |         db_field_types = field_describe.get("db_field_types") | ||||||
|  |         db_column = field_describe.get("db_column") | ||||||
|  |         datatype = db_field_types.get(self.DIALECT) or db_field_types.get("") | ||||||
|         return self._MODIFY_COLUMN_TEMPLATE.format( |         return self._MODIFY_COLUMN_TEMPLATE.format( | ||||||
|             table_name=db_table, |             table_name=db_table, | ||||||
|             column=field_describe.get("db_column"), |             column=db_column, | ||||||
|             datatype=db_field_types.get(self.DIALECT) or db_field_types.get(""), |             datatype=datatype, | ||||||
|  |             using=f' USING "{db_column}"::{datatype}', | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     def set_comment(self, model: "Type[Model]", field_describe: dict): |     def set_comment(self, model: "Type[Model]", field_describe: dict): | ||||||
|   | |||||||
| @@ -392,6 +392,9 @@ class Migrate: | |||||||
|                         elif option == "default": |                         elif option == "default": | ||||||
|                             # change column default |                             # change column default | ||||||
|                             cls._add_operator(cls._alter_default(model, new_data_field), upgrade) |                             cls._add_operator(cls._alter_default(model, new_data_field), upgrade) | ||||||
|  |                         elif option == "unique": | ||||||
|  |                             # because indexed include it | ||||||
|  |                             pass | ||||||
|                         else: |                         else: | ||||||
|                             # modify column |                             # modify column | ||||||
|                             cls._add_operator( |                             cls._add_operator( | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 75 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 76 KiB | 
| @@ -76,7 +76,10 @@ def test_modify_column(): | |||||||
|     if isinstance(Migrate.ddl, MysqlDDL): |     if isinstance(Migrate.ddl, MysqlDDL): | ||||||
|         assert ret0 == "ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200)" |         assert ret0 == "ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200)" | ||||||
|     elif isinstance(Migrate.ddl, PostgresDDL): |     elif isinstance(Migrate.ddl, PostgresDDL): | ||||||
|         assert ret0 == 'ALTER TABLE "category" ALTER COLUMN "name" TYPE VARCHAR(200)' |         assert ( | ||||||
|  |             ret0 | ||||||
|  |             == 'ALTER TABLE "category" ALTER COLUMN "name" TYPE VARCHAR(200) USING "name"::VARCHAR(200)' | ||||||
|  |         ) | ||||||
|  |  | ||||||
|     if isinstance(Migrate.ddl, MysqlDDL): |     if isinstance(Migrate.ddl, MysqlDDL): | ||||||
|         assert ( |         assert ( | ||||||
| @@ -84,7 +87,9 @@ def test_modify_column(): | |||||||
|             == "ALTER TABLE `user` MODIFY COLUMN `is_active` BOOL NOT NULL  COMMENT 'Is Active' DEFAULT 1" |             == "ALTER TABLE `user` MODIFY COLUMN `is_active` BOOL NOT NULL  COMMENT 'Is Active' DEFAULT 1" | ||||||
|         ) |         ) | ||||||
|     elif isinstance(Migrate.ddl, PostgresDDL): |     elif isinstance(Migrate.ddl, PostgresDDL): | ||||||
|         assert ret1 == 'ALTER TABLE "user" ALTER COLUMN "is_active" TYPE BOOL' |         assert ( | ||||||
|  |             ret1 == 'ALTER TABLE "user" ALTER COLUMN "is_active" TYPE BOOL USING "is_active"::BOOL' | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
| def test_alter_column_default(): | def test_alter_column_default(): | ||||||
|   | |||||||
| @@ -768,7 +768,7 @@ def test_migrate(mocker: MockerFixture): | |||||||
|     - alter default: Config.status |     - alter default: Config.status | ||||||
|     - rename column: Product.image -> Product.pic |     - rename column: Product.image -> Product.pic | ||||||
|     """ |     """ | ||||||
|     mocker.patch("click.prompt", side_effect=(False, True)) |     mocker.patch("click.prompt", side_effect=(True,)) | ||||||
|  |  | ||||||
|     models_describe = get_models_describe("models") |     models_describe = get_models_describe("models") | ||||||
|     Migrate.app = "models" |     Migrate.app = "models" | ||||||
| @@ -798,7 +798,6 @@ def test_migrate(mocker: MockerFixture): | |||||||
|                 "ALTER TABLE `product` ALTER COLUMN `view_num` SET DEFAULT 0", |                 "ALTER TABLE `product` ALTER COLUMN `view_num` SET DEFAULT 0", | ||||||
|                 "ALTER TABLE `user` DROP COLUMN `avatar`", |                 "ALTER TABLE `user` DROP COLUMN `avatar`", | ||||||
|                 "ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(100) NOT NULL", |                 "ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(100) NOT NULL", | ||||||
|                 "ALTER TABLE `user` MODIFY COLUMN `username` VARCHAR(20) NOT NULL", |  | ||||||
|                 "CREATE TABLE IF NOT EXISTS `newmodel` (\n    `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,\n    `name` VARCHAR(50) NOT NULL\n) CHARACTER SET utf8mb4;", |                 "CREATE TABLE IF NOT EXISTS `newmodel` (\n    `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,\n    `name` VARCHAR(50) NOT NULL\n) CHARACTER SET utf8mb4;", | ||||||
|                 "ALTER TABLE `user` ADD UNIQUE INDEX `uid_user_usernam_9987ab` (`username`)", |                 "ALTER TABLE `user` ADD UNIQUE INDEX `uid_user_usernam_9987ab` (`username`)", | ||||||
|                 "CREATE TABLE `email_user` (`email_id` INT NOT NULL REFERENCES `email` (`email_id`) ON DELETE CASCADE,`user_id` INT NOT NULL REFERENCES `user` (`id`) ON DELETE CASCADE) CHARACTER SET utf8mb4", |                 "CREATE TABLE `email_user` (`email_id` INT NOT NULL REFERENCES `email` (`email_id`) ON DELETE CASCADE,`user_id` INT NOT NULL REFERENCES `user` (`id`) ON DELETE CASCADE) CHARACTER SET utf8mb4", | ||||||
| @@ -823,7 +822,6 @@ def test_migrate(mocker: MockerFixture): | |||||||
|                 "ALTER TABLE `user` ADD `avatar` VARCHAR(200) NOT NULL  DEFAULT ''", |                 "ALTER TABLE `user` ADD `avatar` VARCHAR(200) NOT NULL  DEFAULT ''", | ||||||
|                 "ALTER TABLE `user` DROP INDEX `idx_user_usernam_9987ab`", |                 "ALTER TABLE `user` DROP INDEX `idx_user_usernam_9987ab`", | ||||||
|                 "ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(200) NOT NULL", |                 "ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(200) NOT NULL", | ||||||
|                 "ALTER TABLE `user` MODIFY COLUMN `username` VARCHAR(20) NOT NULL", |  | ||||||
|                 "DROP TABLE IF EXISTS `email_user`", |                 "DROP TABLE IF EXISTS `email_user`", | ||||||
|                 "DROP TABLE IF EXISTS `newmodel`", |                 "DROP TABLE IF EXISTS `newmodel`", | ||||||
|             ] |             ] | ||||||
| @@ -832,8 +830,8 @@ def test_migrate(mocker: MockerFixture): | |||||||
|     elif isinstance(Migrate.ddl, PostgresDDL): |     elif isinstance(Migrate.ddl, PostgresDDL): | ||||||
|         assert sorted(Migrate.upgrade_operators) == sorted( |         assert sorted(Migrate.upgrade_operators) == sorted( | ||||||
|             [ |             [ | ||||||
|                 'ALTER TABLE "category" ALTER COLUMN "name" TYPE VARCHAR(200)', |                 'ALTER TABLE "category" ALTER COLUMN "name" TYPE VARCHAR(200) USING "name"::VARCHAR(200)', | ||||||
|                 'ALTER TABLE "category" ALTER COLUMN "slug" TYPE VARCHAR(100)', |                 'ALTER TABLE "category" ALTER COLUMN "slug" TYPE VARCHAR(100) USING "slug"::VARCHAR(100)', | ||||||
|                 'ALTER TABLE "config" ADD "user_id" INT NOT NULL', |                 'ALTER TABLE "config" ADD "user_id" INT NOT NULL', | ||||||
|                 'ALTER TABLE "config" ADD CONSTRAINT "fk_config_user_17daa970" FOREIGN KEY ("user_id") REFERENCES "user" ("id") ON DELETE CASCADE', |                 'ALTER TABLE "config" ADD CONSTRAINT "fk_config_user_17daa970" FOREIGN KEY ("user_id") REFERENCES "user" ("id") ON DELETE CASCADE', | ||||||
|                 'ALTER TABLE "config" ALTER COLUMN "status" DROP DEFAULT', |                 'ALTER TABLE "config" ALTER COLUMN "status" DROP DEFAULT', | ||||||
| @@ -843,11 +841,10 @@ def test_migrate(mocker: MockerFixture): | |||||||
|                 'ALTER TABLE "email" RENAME COLUMN "id" TO "email_id"', |                 'ALTER TABLE "email" RENAME COLUMN "id" TO "email_id"', | ||||||
|                 'ALTER TABLE "email" DROP CONSTRAINT "fk_email_user_5b58673d"', |                 'ALTER TABLE "email" DROP CONSTRAINT "fk_email_user_5b58673d"', | ||||||
|                 'CREATE INDEX "idx_email_email_4a1a33" ON "email" ("email")', |                 'CREATE INDEX "idx_email_email_4a1a33" ON "email" ("email")', | ||||||
|                 'ALTER TABLE "user" ALTER COLUMN "username" TYPE VARCHAR(20)', |  | ||||||
|                 'CREATE UNIQUE INDEX "uid_product_name_f14935" ON "product" ("name", "type")', |                 'CREATE UNIQUE INDEX "uid_product_name_f14935" ON "product" ("name", "type")', | ||||||
|                 'ALTER TABLE "product" ALTER COLUMN "view_num" SET DEFAULT 0', |                 'ALTER TABLE "product" ALTER COLUMN "view_num" SET DEFAULT 0', | ||||||
|                 'ALTER TABLE "user" DROP COLUMN "avatar"', |                 'ALTER TABLE "user" DROP COLUMN "avatar"', | ||||||
|                 'ALTER TABLE "user" ALTER COLUMN "password" TYPE VARCHAR(100)', |                 'ALTER TABLE "user" ALTER COLUMN "password" TYPE VARCHAR(100) USING "password"::VARCHAR(100)', | ||||||
|                 '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_user_usernam_9987ab" ON "user" ("username")', |                 'CREATE UNIQUE INDEX "uid_user_usernam_9987ab" ON "user" ("username")', | ||||||
|                 'CREATE TABLE "email_user" ("email_id" INT NOT NULL REFERENCES "email" ("email_id") ON DELETE CASCADE,"user_id" INT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE)', |                 'CREATE TABLE "email_user" ("email_id" INT NOT NULL REFERENCES "email" ("email_id") ON DELETE CASCADE,"user_id" INT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE)', | ||||||
| @@ -855,10 +852,9 @@ def test_migrate(mocker: MockerFixture): | |||||||
|         ) |         ) | ||||||
|         assert sorted(Migrate.downgrade_operators) == sorted( |         assert sorted(Migrate.downgrade_operators) == sorted( | ||||||
|             [ |             [ | ||||||
|                 'ALTER TABLE "category" ALTER COLUMN "name" TYPE VARCHAR(200)', |                 'ALTER TABLE "category" ALTER COLUMN "name" TYPE VARCHAR(200) USING "name"::VARCHAR(200)', | ||||||
|                 'ALTER TABLE "category" ALTER COLUMN "slug" TYPE VARCHAR(200)', |                 'ALTER TABLE "category" ALTER COLUMN "slug" TYPE VARCHAR(200) USING "slug"::VARCHAR(200)', | ||||||
|                 'ALTER TABLE "user" ALTER COLUMN "password" TYPE VARCHAR(200)', |                 'ALTER TABLE "user" ALTER COLUMN "password" TYPE VARCHAR(200) USING "password"::VARCHAR(200)', | ||||||
|                 'ALTER TABLE "user" ALTER COLUMN "username" TYPE VARCHAR(20)', |  | ||||||
|                 'ALTER TABLE "config" DROP COLUMN "user_id"', |                 'ALTER TABLE "config" DROP COLUMN "user_id"', | ||||||
|                 'ALTER TABLE "config" DROP CONSTRAINT "fk_config_user_17daa970"', |                 'ALTER TABLE "config" DROP CONSTRAINT "fk_config_user_17daa970"', | ||||||
|                 'ALTER TABLE "config" ALTER COLUMN "status" SET DEFAULT 1', |                 'ALTER TABLE "config" ALTER COLUMN "status" SET DEFAULT 1', | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user