ソースを参照

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]:


読み込み中…
キャンセル
保存