From cfc905b567cb316b37c8dd7eeb006ebd2ded5144 Mon Sep 17 00:00:00 2001 From: phot0n Date: Sat, 30 Apr 2022 16:16:41 +0530 Subject: [PATCH] fix: use cast when chaninging name type from varchar to bigint in postgres --- frappe/core/doctype/doctype/doctype.py | 15 ++++++++++----- frappe/database/postgres/database.py | 7 ++++--- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index f906011d97..18ab59544b 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -125,6 +125,9 @@ class DocType(Document): if self.default_print_format and not self.custom: frappe.throw(_("Standard DocType cannot have default print format, use Customize Form")) + if self.can_change_name_type: + setup_name_type_and_sequence(self) + def validate_field_name_conflicts(self): """Check if field names dont conflict with controller properties and methods""" core_doctypes = [ @@ -172,9 +175,6 @@ class DocType(Document): ) def after_insert(self): - if self.can_change_name_type: - setup_name_type_and_sequence(self) - # clear user cache so that on the next reload this doctype is included in boot clear_user_cache(frappe.session.user) @@ -954,10 +954,15 @@ def setup_name_type_and_sequence(dt: DocType) -> None: def change_name_column_type(doctype_name: str, type: str) -> None: - frappe.db.change_column_type( - doctype_name, "name", type, True if frappe.db.db_type == "mariadb" else False + # postgres requires cast when converting from varchar to bigint + args = ( + (doctype_name, "name", type, False, True) + if (frappe.db.db_type == "postgres") + else (doctype_name, "name", type, True) ) + frappe.db.change_column_type(*args) + def validate_links_table_fieldnames(meta): """Validate fieldnames in Links table""" diff --git a/frappe/database/postgres/database.py b/frappe/database/postgres/database.py index 15ba86aeba..3334f0ecd8 100644 --- a/frappe/database/postgres/database.py +++ b/frappe/database/postgres/database.py @@ -211,18 +211,19 @@ class PostgresDatabase(Database): ) def change_column_type( - self, doctype: str, column: str, type: str, nullable: bool = False + self, doctype: str, column: str, type: str, nullable: bool = False, use_cast: bool = False ) -> Union[List, Tuple]: table_name = get_table_name(doctype) null_constraint = "SET NOT NULL" if not nullable else "DROP NOT NULL" + using_cast = f'using "{column}"::{type}' if use_cast else "" # postgres allows ddl in transactions but since we've currently made # things same as mariadb (raising exception on ddl commands if the transaction has any writes), # hence using sql_ddl here for committing and then moving forward. return self.sql_ddl( f"""ALTER TABLE "{table_name}" - ALTER COLUMN "{column}" TYPE {type}, - ALTER COLUMN "{column}" {null_constraint}""" + ALTER COLUMN "{column}" TYPE {type} {using_cast}, + ALTER COLUMN "{column}" {null_constraint}""" ) def create_auth_table(self):