We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py`
Content:
```
1 from dateutil.parser import parse
2 
3 from great_expectations.execution_engine import (
4     PandasExecutionEngine,
5     SqlAlchemyExecutionEngine,
6 )
7 from great_expectations.expectations.metrics.import_manager import sa
8 from great_expectations.expectations.metrics.map_metric_provider import (
9     ColumnPairMapMetricProvider,
10     column_pair_condition_partial,
11 )
12 
13 
14 class ColumnPairValuesEqual(ColumnPairMapMetricProvider):
15     condition_metric_name = "column_pair_values.equal"
16     condition_domain_keys = (
17         "batch_id",
18         "table",
19         "column_A",
20         "column_B",
21         "row_condition",
22         "condition_parser",
23         "ignore_row_if",
24     )
25     condition_value_keys = ()
26 
27     # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>
28     @column_pair_condition_partial(engine=PandasExecutionEngine)
29     def _pandas(cls, column_A, column_B, **kwargs):
30         return column_A == column_B
31 
32     @column_pair_condition_partial(engine=SqlAlchemyExecutionEngine)
33     def _sqlalchemy(cls, column_A, column_B, **kwargs):
34         return sa.case((column_A == column_B, True), else_=False)
35
```

Path: `great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py`
Content:
```
1 from dateutil.parser import parse
2 
3 from great_expectations.execution_engine import (
4     PandasExecutionEngine,
5     SqlAlchemyExecutionEngine,
6 )
7 from great_expectations.expectations.metrics.import_manager import sa
8 from great_expectations.expectations.metrics.map_metric_provider import (
9     ColumnPairMapMetricProvider,
10     column_pair_condition_partial,
11 )
12 
13 
14 class ColumnPairValuesAGreaterThanB(ColumnPairMapMetricProvider):
15     condition_metric_name = "column_pair_values.a_greater_than_b"
16     condition_domain_keys = (
17         "batch_id",
18         "table",
19         "column_A",
20         "column_B",
21         "row_condition",
22         "condition_parser",
23         "ignore_row_if",
24     )
25     condition_value_keys = (
26         "or_equal",
27         "parse_strings_as_datetimes",
28         "allow_cross_type_comparisons",
29     )
30 
31     # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>
32     # noinspection PyPep8Naming
33     @column_pair_condition_partial(engine=PandasExecutionEngine)
34     def _pandas(cls, column_A, column_B, **kwargs):
35         allow_cross_type_comparisons = kwargs.get("allow_cross_type_comparisons")
36         if allow_cross_type_comparisons:
37             raise NotImplementedError
38 
39         parse_strings_as_datetimes = kwargs.get("parse_strings_as_datetimes")
40         if parse_strings_as_datetimes:
41             # noinspection PyPep8Naming
42             temp_column_A = column_A.map(parse)
43             # noinspection PyPep8Naming
44             temp_column_B = column_B.map(parse)
45         else:
46             temp_column_A = column_A
47             temp_column_B = column_B
48 
49         or_equal = kwargs.get("or_equal")
50         if or_equal:
51             return temp_column_A >= temp_column_B
52         else:
53             return temp_column_A > temp_column_B
54 
55     # noinspection PyPep8Naming
56     @column_pair_condition_partial(engine=SqlAlchemyExecutionEngine)
57     def _sqlalchemy(cls, column_A, column_B, **kwargs):
58         allow_cross_type_comparisons = kwargs.get("allow_cross_type_comparisons")
59         if allow_cross_type_comparisons:
60             raise NotImplementedError
61 
62         parse_strings_as_datetimes = kwargs.get("parse_strings_as_datetimes")
63         if parse_strings_as_datetimes:
64             raise NotImplementedError
65 
66         or_equal = kwargs.get("or_equal")
67         if or_equal:
68             return sa.case((column_A >= column_B, True), else_=False)
69         else:
70             return sa.case((column_A > column_B, True), else_=False)
71
```

Path: `great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py`
Content:
```
1 from great_expectations.execution_engine import PandasExecutionEngine
2 from great_expectations.expectations.metrics.map_metric_provider import (
3     MulticolumnMapMetricProvider,
4     multicolumn_condition_partial,
5 )
6 
7 
8 class SelectColumnValuesUniqueWithinRecord(MulticolumnMapMetricProvider):
9     condition_metric_name = "select_column_values.unique.within_record"
10     condition_domain_keys = (
11         "batch_id",
12         "table",
13         "column_list",
14         "row_condition",
15         "condition_parser",
16         "ignore_row_if",
17     )
18 
19     # TODO: <Alex>ALEX -- temporarily only a Pandas implementation is provided (others to follow).</Alex>
20     @multicolumn_condition_partial(engine=PandasExecutionEngine)
21     def _pandas(cls, column_list, **kwargs):
22         num_columns = len(column_list.columns)
23         row_wise_cond = column_list.nunique(dropna=False, axis=1) >= num_columns
24         return row_wise_cond
25
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py b/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py
--- a/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py
+++ b/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py
@@ -1,5 +1,3 @@
-from dateutil.parser import parse
-
 from great_expectations.execution_engine import (
     PandasExecutionEngine,
     SqlAlchemyExecutionEngine,
diff --git a/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py b/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py
--- a/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py
+++ b/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py
@@ -38,9 +38,7 @@
 
         parse_strings_as_datetimes = kwargs.get("parse_strings_as_datetimes")
         if parse_strings_as_datetimes:
-            # noinspection PyPep8Naming
             temp_column_A = column_A.map(parse)
-            # noinspection PyPep8Naming
             temp_column_B = column_B.map(parse)
         else:
             temp_column_A = column_A
diff --git a/great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py b/great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py
--- a/great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py
+++ b/great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py
@@ -1,9 +1,17 @@
-from great_expectations.execution_engine import PandasExecutionEngine
+import logging
+
+from great_expectations.execution_engine import (
+    PandasExecutionEngine,
+    SqlAlchemyExecutionEngine,
+)
+from great_expectations.expectations.metrics.import_manager import sa
 from great_expectations.expectations.metrics.map_metric_provider import (
     MulticolumnMapMetricProvider,
     multicolumn_condition_partial,
 )
 
+logger = logging.getLogger(__name__)
+
 
 class SelectColumnValuesUniqueWithinRecord(MulticolumnMapMetricProvider):
     condition_metric_name = "select_column_values.unique.within_record"
@@ -16,9 +24,37 @@
         "ignore_row_if",
     )
 
-    # TODO: <Alex>ALEX -- temporarily only a Pandas implementation is provided (others to follow).</Alex>
+    # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>
     @multicolumn_condition_partial(engine=PandasExecutionEngine)
     def _pandas(cls, column_list, **kwargs):
         num_columns = len(column_list.columns)
         row_wise_cond = column_list.nunique(dropna=False, axis=1) >= num_columns
         return row_wise_cond
+
+    @multicolumn_condition_partial(engine=SqlAlchemyExecutionEngine)
+    def _sqlalchemy(cls, column_list, **kwargs):
+        """
+        The present approach relies on an inefficient query condition construction implementation, whose computational
+        cost is O(num_columns^2).  However, until a more efficient implementation compatible with SQLAlchemy is
+        available, this is the only feasible mechanism under the current architecture, where map metric providers must
+        return a condition.  Nevertheless, SQL query length limit is 1GB (sufficient for most practical scenarios).
+        """
+        num_columns = len(column_list)
+
+        # An arbitrary "num_columns" value used for issuing an explanatory message as a warning.
+        if num_columns > 100:
+            logger.warning(
+                f"""Batch data with {num_columns} columns is detected.  Computing the "{cls.condition_metric_name}" \
+metric for wide tables using SQLAlchemy leads to long WHERE clauses for the underlying database engine to process.
+"""
+            )
+
+        condition = sa.or_()
+        for idx_src in range(num_columns - 1):
+            for idx_dest in range(idx_src + 1, num_columns):
+                condition = sa.or_(
+                    condition, (column_list[idx_src] == column_list[idx_dest])
+                )
+
+        condition = sa.not_(condition)
+        return sa.case((condition, True), else_=False)

{"golden_diff": "diff --git a/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py b/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py\n--- a/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py\n+++ b/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py\n@@ -1,5 +1,3 @@\n-from dateutil.parser import parse\n-\n from great_expectations.execution_engine import (\n     PandasExecutionEngine,\n     SqlAlchemyExecutionEngine,\ndiff --git a/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py b/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py\n--- a/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py\n+++ b/great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py\n@@ -38,9 +38,7 @@\n \n         parse_strings_as_datetimes = kwargs.get(\"parse_strings_as_datetimes\")\n         if parse_strings_as_datetimes:\n-            # noinspection PyPep8Naming\n             temp_column_A = column_A.map(parse)\n-            # noinspection PyPep8Naming\n             temp_column_B = column_B.map(parse)\n         else:\n             temp_column_A = column_A\ndiff --git a/great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py b/great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py\n--- a/great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py\n+++ b/great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py\n@@ -1,9 +1,17 @@\n-from great_expectations.execution_engine import PandasExecutionEngine\n+import logging\n+\n+from great_expectations.execution_engine import (\n+    PandasExecutionEngine,\n+    SqlAlchemyExecutionEngine,\n+)\n+from great_expectations.expectations.metrics.import_manager import sa\n from great_expectations.expectations.metrics.map_metric_provider import (\n     MulticolumnMapMetricProvider,\n     multicolumn_condition_partial,\n )\n \n+logger = logging.getLogger(__name__)\n+\n \n class SelectColumnValuesUniqueWithinRecord(MulticolumnMapMetricProvider):\n     condition_metric_name = \"select_column_values.unique.within_record\"\n@@ -16,9 +24,37 @@\n         \"ignore_row_if\",\n     )\n \n-    # TODO: <Alex>ALEX -- temporarily only a Pandas implementation is provided (others to follow).</Alex>\n+    # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>\n     @multicolumn_condition_partial(engine=PandasExecutionEngine)\n     def _pandas(cls, column_list, **kwargs):\n         num_columns = len(column_list.columns)\n         row_wise_cond = column_list.nunique(dropna=False, axis=1) >= num_columns\n         return row_wise_cond\n+\n+    @multicolumn_condition_partial(engine=SqlAlchemyExecutionEngine)\n+    def _sqlalchemy(cls, column_list, **kwargs):\n+        \"\"\"\n+        The present approach relies on an inefficient query condition construction implementation, whose computational\n+        cost is O(num_columns^2).  However, until a more efficient implementation compatible with SQLAlchemy is\n+        available, this is the only feasible mechanism under the current architecture, where map metric providers must\n+        return a condition.  Nevertheless, SQL query length limit is 1GB (sufficient for most practical scenarios).\n+        \"\"\"\n+        num_columns = len(column_list)\n+\n+        # An arbitrary \"num_columns\" value used for issuing an explanatory message as a warning.\n+        if num_columns > 100:\n+            logger.warning(\n+                f\"\"\"Batch data with {num_columns} columns is detected.  Computing the \"{cls.condition_metric_name}\" \\\n+metric for wide tables using SQLAlchemy leads to long WHERE clauses for the underlying database engine to process.\n+\"\"\"\n+            )\n+\n+        condition = sa.or_()\n+        for idx_src in range(num_columns - 1):\n+            for idx_dest in range(idx_src + 1, num_columns):\n+                condition = sa.or_(\n+                    condition, (column_list[idx_src] == column_list[idx_dest])\n+                )\n+\n+        condition = sa.not_(condition)\n+        return sa.case((condition, True), else_=False)\n", "issue": "Use cleaner solution for non-truncating division in python 2\nPrefer `from __future__ import division` to `1.*x/y`\n", "before_files": [{"content": "from dateutil.parser import parse\n\nfrom great_expectations.execution_engine import (\n    PandasExecutionEngine,\n    SqlAlchemyExecutionEngine,\n)\nfrom great_expectations.expectations.metrics.import_manager import sa\nfrom great_expectations.expectations.metrics.map_metric_provider import (\n    ColumnPairMapMetricProvider,\n    column_pair_condition_partial,\n)\n\n\nclass ColumnPairValuesEqual(ColumnPairMapMetricProvider):\n    condition_metric_name = \"column_pair_values.equal\"\n    condition_domain_keys = (\n        \"batch_id\",\n        \"table\",\n        \"column_A\",\n        \"column_B\",\n        \"row_condition\",\n        \"condition_parser\",\n        \"ignore_row_if\",\n    )\n    condition_value_keys = ()\n\n    # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>\n    @column_pair_condition_partial(engine=PandasExecutionEngine)\n    def _pandas(cls, column_A, column_B, **kwargs):\n        return column_A == column_B\n\n    @column_pair_condition_partial(engine=SqlAlchemyExecutionEngine)\n    def _sqlalchemy(cls, column_A, column_B, **kwargs):\n        return sa.case((column_A == column_B, True), else_=False)\n", "path": "great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py"}, {"content": "from dateutil.parser import parse\n\nfrom great_expectations.execution_engine import (\n    PandasExecutionEngine,\n    SqlAlchemyExecutionEngine,\n)\nfrom great_expectations.expectations.metrics.import_manager import sa\nfrom great_expectations.expectations.metrics.map_metric_provider import (\n    ColumnPairMapMetricProvider,\n    column_pair_condition_partial,\n)\n\n\nclass ColumnPairValuesAGreaterThanB(ColumnPairMapMetricProvider):\n    condition_metric_name = \"column_pair_values.a_greater_than_b\"\n    condition_domain_keys = (\n        \"batch_id\",\n        \"table\",\n        \"column_A\",\n        \"column_B\",\n        \"row_condition\",\n        \"condition_parser\",\n        \"ignore_row_if\",\n    )\n    condition_value_keys = (\n        \"or_equal\",\n        \"parse_strings_as_datetimes\",\n        \"allow_cross_type_comparisons\",\n    )\n\n    # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>\n    # noinspection PyPep8Naming\n    @column_pair_condition_partial(engine=PandasExecutionEngine)\n    def _pandas(cls, column_A, column_B, **kwargs):\n        allow_cross_type_comparisons = kwargs.get(\"allow_cross_type_comparisons\")\n        if allow_cross_type_comparisons:\n            raise NotImplementedError\n\n        parse_strings_as_datetimes = kwargs.get(\"parse_strings_as_datetimes\")\n        if parse_strings_as_datetimes:\n            # noinspection PyPep8Naming\n            temp_column_A = column_A.map(parse)\n            # noinspection PyPep8Naming\n            temp_column_B = column_B.map(parse)\n        else:\n            temp_column_A = column_A\n            temp_column_B = column_B\n\n        or_equal = kwargs.get(\"or_equal\")\n        if or_equal:\n            return temp_column_A >= temp_column_B\n        else:\n            return temp_column_A > temp_column_B\n\n    # noinspection PyPep8Naming\n    @column_pair_condition_partial(engine=SqlAlchemyExecutionEngine)\n    def _sqlalchemy(cls, column_A, column_B, **kwargs):\n        allow_cross_type_comparisons = kwargs.get(\"allow_cross_type_comparisons\")\n        if allow_cross_type_comparisons:\n            raise NotImplementedError\n\n        parse_strings_as_datetimes = kwargs.get(\"parse_strings_as_datetimes\")\n        if parse_strings_as_datetimes:\n            raise NotImplementedError\n\n        or_equal = kwargs.get(\"or_equal\")\n        if or_equal:\n            return sa.case((column_A >= column_B, True), else_=False)\n        else:\n            return sa.case((column_A > column_B, True), else_=False)\n", "path": "great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py"}, {"content": "from great_expectations.execution_engine import PandasExecutionEngine\nfrom great_expectations.expectations.metrics.map_metric_provider import (\n    MulticolumnMapMetricProvider,\n    multicolumn_condition_partial,\n)\n\n\nclass SelectColumnValuesUniqueWithinRecord(MulticolumnMapMetricProvider):\n    condition_metric_name = \"select_column_values.unique.within_record\"\n    condition_domain_keys = (\n        \"batch_id\",\n        \"table\",\n        \"column_list\",\n        \"row_condition\",\n        \"condition_parser\",\n        \"ignore_row_if\",\n    )\n\n    # TODO: <Alex>ALEX -- temporarily only a Pandas implementation is provided (others to follow).</Alex>\n    @multicolumn_condition_partial(engine=PandasExecutionEngine)\n    def _pandas(cls, column_list, **kwargs):\n        num_columns = len(column_list.columns)\n        row_wise_cond = column_list.nunique(dropna=False, axis=1) >= num_columns\n        return row_wise_cond\n", "path": "great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py"}], "after_files": [{"content": "from great_expectations.execution_engine import (\n    PandasExecutionEngine,\n    SqlAlchemyExecutionEngine,\n)\nfrom great_expectations.expectations.metrics.import_manager import sa\nfrom great_expectations.expectations.metrics.map_metric_provider import (\n    ColumnPairMapMetricProvider,\n    column_pair_condition_partial,\n)\n\n\nclass ColumnPairValuesEqual(ColumnPairMapMetricProvider):\n    condition_metric_name = \"column_pair_values.equal\"\n    condition_domain_keys = (\n        \"batch_id\",\n        \"table\",\n        \"column_A\",\n        \"column_B\",\n        \"row_condition\",\n        \"condition_parser\",\n        \"ignore_row_if\",\n    )\n    condition_value_keys = ()\n\n    # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>\n    @column_pair_condition_partial(engine=PandasExecutionEngine)\n    def _pandas(cls, column_A, column_B, **kwargs):\n        return column_A == column_B\n\n    @column_pair_condition_partial(engine=SqlAlchemyExecutionEngine)\n    def _sqlalchemy(cls, column_A, column_B, **kwargs):\n        return sa.case((column_A == column_B, True), else_=False)\n", "path": "great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_equal.py"}, {"content": "from dateutil.parser import parse\n\nfrom great_expectations.execution_engine import (\n    PandasExecutionEngine,\n    SqlAlchemyExecutionEngine,\n)\nfrom great_expectations.expectations.metrics.import_manager import sa\nfrom great_expectations.expectations.metrics.map_metric_provider import (\n    ColumnPairMapMetricProvider,\n    column_pair_condition_partial,\n)\n\n\nclass ColumnPairValuesAGreaterThanB(ColumnPairMapMetricProvider):\n    condition_metric_name = \"column_pair_values.a_greater_than_b\"\n    condition_domain_keys = (\n        \"batch_id\",\n        \"table\",\n        \"column_A\",\n        \"column_B\",\n        \"row_condition\",\n        \"condition_parser\",\n        \"ignore_row_if\",\n    )\n    condition_value_keys = (\n        \"or_equal\",\n        \"parse_strings_as_datetimes\",\n        \"allow_cross_type_comparisons\",\n    )\n\n    # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>\n    # noinspection PyPep8Naming\n    @column_pair_condition_partial(engine=PandasExecutionEngine)\n    def _pandas(cls, column_A, column_B, **kwargs):\n        allow_cross_type_comparisons = kwargs.get(\"allow_cross_type_comparisons\")\n        if allow_cross_type_comparisons:\n            raise NotImplementedError\n\n        parse_strings_as_datetimes = kwargs.get(\"parse_strings_as_datetimes\")\n        if parse_strings_as_datetimes:\n            temp_column_A = column_A.map(parse)\n            temp_column_B = column_B.map(parse)\n        else:\n            temp_column_A = column_A\n            temp_column_B = column_B\n\n        or_equal = kwargs.get(\"or_equal\")\n        if or_equal:\n            return temp_column_A >= temp_column_B\n        else:\n            return temp_column_A > temp_column_B\n\n    # noinspection PyPep8Naming\n    @column_pair_condition_partial(engine=SqlAlchemyExecutionEngine)\n    def _sqlalchemy(cls, column_A, column_B, **kwargs):\n        allow_cross_type_comparisons = kwargs.get(\"allow_cross_type_comparisons\")\n        if allow_cross_type_comparisons:\n            raise NotImplementedError\n\n        parse_strings_as_datetimes = kwargs.get(\"parse_strings_as_datetimes\")\n        if parse_strings_as_datetimes:\n            raise NotImplementedError\n\n        or_equal = kwargs.get(\"or_equal\")\n        if or_equal:\n            return sa.case((column_A >= column_B, True), else_=False)\n        else:\n            return sa.case((column_A > column_B, True), else_=False)\n", "path": "great_expectations/expectations/metrics/column_pair_map_metrics/column_pair_values_greater.py"}, {"content": "import logging\n\nfrom great_expectations.execution_engine import (\n    PandasExecutionEngine,\n    SqlAlchemyExecutionEngine,\n)\nfrom great_expectations.expectations.metrics.import_manager import sa\nfrom great_expectations.expectations.metrics.map_metric_provider import (\n    MulticolumnMapMetricProvider,\n    multicolumn_condition_partial,\n)\n\nlogger = logging.getLogger(__name__)\n\n\nclass SelectColumnValuesUniqueWithinRecord(MulticolumnMapMetricProvider):\n    condition_metric_name = \"select_column_values.unique.within_record\"\n    condition_domain_keys = (\n        \"batch_id\",\n        \"table\",\n        \"column_list\",\n        \"row_condition\",\n        \"condition_parser\",\n        \"ignore_row_if\",\n    )\n\n    # TODO: <Alex>ALEX -- temporarily only Pandas and SQL Alchemy implementations are provided (Spark to follow).</Alex>\n    @multicolumn_condition_partial(engine=PandasExecutionEngine)\n    def _pandas(cls, column_list, **kwargs):\n        num_columns = len(column_list.columns)\n        row_wise_cond = column_list.nunique(dropna=False, axis=1) >= num_columns\n        return row_wise_cond\n\n    @multicolumn_condition_partial(engine=SqlAlchemyExecutionEngine)\n    def _sqlalchemy(cls, column_list, **kwargs):\n        \"\"\"\n        The present approach relies on an inefficient query condition construction implementation, whose computational\n        cost is O(num_columns^2).  However, until a more efficient implementation compatible with SQLAlchemy is\n        available, this is the only feasible mechanism under the current architecture, where map metric providers must\n        return a condition.  Nevertheless, SQL query length limit is 1GB (sufficient for most practical scenarios).\n        \"\"\"\n        num_columns = len(column_list)\n\n        # An arbitrary \"num_columns\" value used for issuing an explanatory message as a warning.\n        if num_columns > 100:\n            logger.warning(\n                f\"\"\"Batch data with {num_columns} columns is detected.  Computing the \"{cls.condition_metric_name}\" \\\nmetric for wide tables using SQLAlchemy leads to long WHERE clauses for the underlying database engine to process.\n\"\"\"\n            )\n\n        condition = sa.or_()\n        for idx_src in range(num_columns - 1):\n            for idx_dest in range(idx_src + 1, num_columns):\n                condition = sa.or_(\n                    condition, (column_list[idx_src] == column_list[idx_dest])\n                )\n\n        condition = sa.not_(condition)\n        return sa.case((condition, True), else_=False)\n", "path": "great_expectations/expectations/metrics/multicolumn_map_metrics/select_column_values_unique_within_record.py"}]}