瀏覽代碼

fix: correct index re-syncing

The implementation of syncing unique and non-unique index depended on
index names which used to be different before because of that there's
tendency to incorrectly identify index.

This PR adds a separate util for checking if a column has index without
relying on naming convention. It just goes and checks if there's any
index with that column in it, hence far more reliable.

(cherry picked from commit cbe4b59100)
version-14
Ankush Menat 2 年之前
committed by Mergify
父節點
當前提交
10e1eed077
共有 2 個檔案被更改,包括 37 行新增30 行删除
  1. +31
    -0
      frappe/database/mariadb/database.py
  2. +6
    -30
      frappe/database/mariadb/schema.py

+ 31
- 0
frappe/database/mariadb/database.py 查看文件

@@ -319,6 +319,37 @@ class MariaDBDatabase(MariaDBConnectionUtil, MariaDBExceptionUtil, Database):
)
)

def get_column_index(
self, table_name: str, fieldname: str, unique: bool = False
) -> frappe._dict | None:
"""Check if column exists for a specific fields in specified order.

This differs from db.has_index because it doesn't rely on index name but columns inside an
index.
"""

indexes = self.sql(
f"""SHOW INDEX FROM `{table_name}`
WHERE Column_name = "{fieldname}"
AND Seq_in_index = 1
AND Non_unique={int(not unique)}
""",
as_dict=True,
)

# Same index can be part of clustered index which contains more fields
# We don't want those.
for index in indexes:
clustered_index = self.sql(
f"""SHOW INDEX FROM `{table_name}`
WHERE Key_name = "{index.Key_name}"
AND Seq_in_index = 2
""",
as_dict=True,
)
if not clustered_index:
return index

def add_index(self, doctype: str, fields: list, index_name: str = None):
"""Creates an index with given fields if not already created.
Index name will be `fieldname1_fieldname2_index`"""


+ 6
- 30
frappe/database/mariadb/schema.py 查看文件

@@ -84,7 +84,7 @@ class MariaDBTable(DBTable):

for col in self.add_index:
# if index key does not exists
if not frappe.db.has_index(self.table_name, col.fieldname + "_index"):
if not frappe.db.get_column_index(self.table_name, col.fieldname, unique=False):
add_index_query.append(f"ADD INDEX `{col.fieldname}_index`(`{col.fieldname}`)")

for col in self.drop_index + self.drop_unique:
@@ -94,37 +94,13 @@ class MariaDBTable(DBTable):
current_column = self.current_columns.get(col.fieldname.lower())
unique_constraint_changed = current_column.unique != col.unique
if unique_constraint_changed and not col.unique:
# nosemgrep
unique_index_record = frappe.db.sql(
"""
SHOW INDEX FROM `{}`
WHERE Key_name=%s
AND Non_unique=0
""".format(
self.table_name
),
(col.fieldname),
as_dict=1,
)
if unique_index_record:
drop_index_query.append(f"DROP INDEX `{unique_index_record[0].Key_name}`")
if unique_index := frappe.db.get_column_index(self.table_name, col.fieldname, unique=True):
drop_index_query.append(f"DROP INDEX `{unique_index.Key_name}`")

index_constraint_changed = current_column.index != col.set_index
# if index key exists
if index_constraint_changed and not col.set_index:
# nosemgrep
index_record = frappe.db.sql(
"""
SHOW INDEX FROM `{}`
WHERE Key_name=%s
AND Non_unique=1
""".format(
self.table_name
),
(col.fieldname + "_index"),
as_dict=1,
)
if index_record:
drop_index_query.append(f"DROP INDEX `{index_record[0].Key_name}`")
if index_record := frappe.db.get_column_index(self.table_name, col.fieldname, unique=False):
drop_index_query.append(f"DROP INDEX `{index_record.Key_name}`")

try:
for query_parts in [add_column_query, modify_column_query, add_index_query, drop_index_query]:


Loading…
取消
儲存