驱动器接口更改日志

Metabase 0.51.0

  • 添加了新的可选方法 metabase.driver/query-result-metadata,用于高效计算查询的元数据,而无需实际运行它们。:sql-jdbc 已提供默认实现;不基于此实现且可以确定结果元数据而不实际运行查询的驱动程序应添加自己的实现,以便在保存问题时获得更好的性能。有关更多信息以及示例实现的查找位置,请参阅方法docstring。

  • 在0.51.0之前,为了生成具有内联参数的SQL查询,Metabase会生成一个参数化的SQL字符串,然后尝试解析SQL替换并将 ? 占位符替换为来自驱动程序方法 metabase.driver.sql.util.unprepare/unprepare-value 的内联值。在0.51.0+中,Metabase改为使用Honey SQL 2的 :inline 选项生成这些查询,消除了解析和替换 ? 占位符的需要。因此,已弃用 metabase.driver.sql.util.unprepare 命名空间;您应从驱动程序中删除其所有用法。

  • 已用新的方法 metabase.driver.sql.query-processor/inline-value 替换了 metabase.driver.sql.util.unprepare/unprepare-value 方法。这两个函数的签名相同,您可以将所有 unprepare-value 实现简单地更改为 inline-value。有关此更改的示例,请参阅 PR #45008

    目前,unprepare-value 的实现自动用作 inline-value 的实现,但计划在0.54.0中删除 unprepare-value

  • metabase.driver.sql.query-processor/format-honeysql 现在是一个多方法,主要以便您可以在需要始终编译而不参数化时绑定 *compile-with-inline-parameters*

  • 已添加动态变量 metabase.driver/*compile-with-inline-parameters*(默认值 false);能够生成参数化查询的驱动程序应在其 metabase.driver/mbql->native 的实现中查看其值,并相应地调整其输出。对于基于 :sql-jdbc 且支持参数化的驱动程序,这已在共享的 metabase.driver.sql.query-processor 代码中处理,因此您不需要在此进行调整。对于不支持 JDBC 风格参数化查询的 :sql 驱动程序,您可以实施 format-honeysql 并将 *compile-with-inline-parameters* 绑定,如上所述。查看 :athena 驱动程序以了解如何实现此功能。

  • 已删除接受参数化 SQL 字符串并取消参数化或“未准备”它的 metabase.driver.sql.util.unprepare/unprepare;相反,如果您需要将参数直接嵌入 SQL 中的查询,请按上述方法绑定 metabase.driver/*compile-with-inline-parameters*

  • 同样,已将驱动程序方法 metabase.driver/splice-parameters-into-native-query 标记为已弃用,并在调用时会抛出异常。重新编写生成参数化查询然后调用 unpreparesplice-parameters-into-native-query 的代码,首先使用上述方法生成带有内联参数的查询。如果需要,测试可以使用 metabase.query-processor.compile/compile-with-inline-parameters

  • 已删除 metabase.query-processor.compile/compile-and-splice-parameters;使用 metabase.query-processor.compile/compile-with-inline-parameters 替换使用情况。

  • 已删除 metabase.driver.sql.query-processor/format-honeysql 的三参数版本(该版本有一个额外的 Honey SQL 版本参数);将所有使用情况替换为双参数版本。自 Metabase 0.49.0 以来,Honey SQL 2 已成为唯一支持的版本。

  • 有时传递给加载和销毁测试数据方法的 :skip-drop-db? 选项不再传递,您可以删除检查它的代码。现在测试数据代码在避免不必要的/重复调用 metabase.test.data.interface/create-db! 方面做得更好,因此测试数据加载代码在加载测试数据之前不应需要调用 DROP DATABASE IF EXISTS

  • 基于 JDBC 的数据库的测试数据加载已进行了一些重写。已删除多方法 metabase.test.data.sql-jdbc.load-data/load-data! 及其辅助函数,以支持几个更易于组合和理解的新多方法。

  • metabase.test.data.sql-jdbc.load-data/row-xform 是在加载测试数据时应用于每一行的转换器。默认实现是 identity,但您可以使用 metabase.test.data.sql-jdbc.load-data/add-ids-xform 为每一行添加 ID(这取代了已删除的 metabase.test.data.sql-jdbc.load-data/load-data-add-ids 函数)和 metabase.test.data.sql-jdbc.load-data/maybe-add-ids-xform(这取代了 metabase.test.data.sql-jdbc.load-data/load-data-maybe-add-ids!metabase.test.data.sql-jdbc.load-data/load-data-maybe-add-ids-chunked!)。

  • metabase.test.data.sql-jdbc.load-data/chunk-size 用于控制每次批量加载的行数。默认值为 200,但您可以实现此方法并返回 nil 以一次性加载所有数据,不受行数限制。不再需要 metabase.test.data.sql-jdbc.load-data/*chunk-size*metabase.test.data.sql-jdbc.load-data/load-data-chunkedmetabase.test.data.sql-jdbc.load-data/load-data-all-at-once!metabase.test.data.sql-jdbc.load-data/load-data-chunked! 等类似函数,并且已经删除。

  • metabase.test.data.sql-jdbc.load-data/chunk-xform 是应用于每个行块(取决于 chunk-size)或整个行组(如果 chunk-sizenil)的转换器。默认值为 identity。它可以用于实现每个块的特殊行为,例如将块写入 CSV 文件以在 metabase.test.data.sql-jdbc.load-data/do-insert! 方法中分别加载。请参见 metabase.test.data.vertica 的示例。

  • 现在连接一次性创建并重用于大量测试数据加载。现在 metabase.test.data.sql-jdbc.load-data/do-insert! 的第二个参数现在是 java.sql.Connection 而不是 clojure.java.jdbc 规范。

  • 同样,现在使用 java.sql.Connection 而不是同时使用 DatabaseDefinition:server:db 上下文来调用 metabase.test.data.sql-jdbc.execute/execute-sql! 和类似函数;适当的连接类型将自动创建并传递到调用代码中。相应地更新您的函数实现和使用方法。

  • 添加了方法 metabase.test.data.interface/dataset-already-loaded? 以检查测试数据集是否已加载。基于 JDBC 的驱动程序具有默认实现,用于检查我们是否可以连接到数据库;您可能需要为那些在测试中实际上不创建新数据库的驱动程序重写此实现。您可以通过运行测试 metabase.test.data.sql-jdbc-test/dataset-already-loaded?-test 来使用默认实现检查您的基于 JDBC 的驱动程序是否正确工作。

  • metabase.test.data.sql.ddl/insert-rows-ddl-statements 已重命名为 metabase.test.data.sql.ddl/insert-rows-dml-statements,因为 INSERT 是 DML 而不是 DDL。请相应地更新您的函数实现。

  • 已删除 :foreign-keys 驱动功能。对于支持在同步期间报告外键关系的驱动程序,应使用 :metadata/keys-constraints。隐式连接现在依赖于 :left-join 功能。对于基于 :sql 的驱动程序,默认值为 true。现在默认启用所有基于 :sql 的驱动程序的连接功能。以前,这些功能依赖于 :foreign-keys 功能。如果您的驱动程序支持 :left-join,则现在将执行重映射和隐式连接的测试。

  • 已添加 :parameterized-sql 驱动功能,以区分在测试中不支持参数化 SQL 的驱动程序。目前,此功能仅在 :sparksql 中禁用。

  • 已删除测试方法 metabase.test.data.interface/supports-time-type?metabase.test.data.interface/supports-timestamptz-type?,分别替换为功能 :test/time-type:test/timestamptz-type。如果您实现了这些方法,请用您的驱动程序的 metabase.driver/database-supports? 实现和相应的功能关键字替换实现。

  • 使用 metabase.driver.sql.query-processor/->honeysql 的驱动程序可以实现 :metabase.driver.sql.query-processor/nfc-path 以包括 nfc-path 在字段标识符中。这样就可以使用 <table>.<record>.<record-field> 引用记录样式的字段。请参阅 bigquery-cloud-sdk 以获取示例。默认为 nil,表示路径不应成为标识符的一部分。

  • 已添加 :test/dynamic-dataset-loading 功能。它使驱动程序能够在测试运行时退出需要创建新数据集的测试。

  • 已添加 :temporal/requires-default-unit 功能。对于大多数驱动程序,它应该是 false,但对于一些(如旧的、预 JDBC Druid 驱动程序)来说,它是必要的,以便找到所有时间字段引用并在它们上放置 :temporal-unit :default。此默认设置以前适用于所有驱动程序,但引入了一些下游问题,因此现在只有需要此功能的驱动程序可以设置此功能。

Metabase 0.50.17

  • 为特定于驱动程序的行为添加了方法 metabase.driver/incorporate-auth-provider-details,用于将身份验证提供程序的响应合并到数据库详情中。在大多数情况下,这意味着根据身份验证提供程序及其响应设置 :password 和/或 :username。

Metabase 0.50.16

  • metabase.types 命名空间中添加了 :type/fingerprinting-unsupported。类似于用于字段值扫描的 :type/field-values-unsupported,它用于确定特定字段是否应该计算其指纹。在撰写本文时,该逻辑在 metabase.sync.analyze.fingerprint/fields-to-fingerprint-base-clause 中执行。

  • metabase.types 命名空间中也添加了 :type/Large。驱动程序作者可以使用它来表示特定字段包含足够大的值以跳过指纹或字段值扫描。它也可以用于未来的其他目的。示例包括 Oracle CLOB 或 Postgres JSON 列。

Metabase 0.50.0

  • Metabase metabase.mbql.* 命名空间已移动到 metabase.legacy-mbql.*。您可能不需要在驱动程序中使用这些命名空间,但如果确实使用了,请更新它们。

  • 添加了多方法 metabase.driver/truncate!。此方法用于以最有效的方式删除表中的行。目前,此功能仅适用于支持 :uploads 功能的驱动程序,并为基于 JDBC 的驱动程序提供了默认实现。

  • 添加了新功能 :window-functions/cumulative。实现此方法的驱动程序应在其本地查询语言中实现累积求和(:cum-sum)和累积计数(:cum-count)聚合子句。对于非 SQL 驱动程序(非基于我们 :sql:sql-jdbc 驱动程序的驱动程序),此功能标志默认设置为 false;将继续使用旧(损坏的)累积聚合的后处理实现。(有关旧实现损坏的更多信息,请参阅问题 #13634#15118。)

    如果可能,非 SQL 驱动程序应更新以本地实现累积聚合。

    SQL 实现使用 OVER (...) 表达式。它将自动将 GROUP BY 表达式(如 date_trunc())移动到 SUBSELECT 中,以便像 BigQuery 这样的挑剔的数据库可以引用普通列标识符。实际生成的 SQL 将类似于

    SELECT
      created_at_month,
      sum(sum(total) OVER (ORDER BY created_at_month ROWS UNBOUNDED PRECEDING) AS cumulative_sum
    FROM (
      SELECT
        date_trunc('month', created_at) AS created_at_month,
        total
      FROM
        my_table
      ) source
    GROUP BY
      created_at_month
    ORDER BY
      created_at_month
    

    非 SQL 驱动程序可以使用 metabase.query-processor.util.transformations.nest-breakouts/nest-breakouts-in-stages-with-window-aggregation 来利用相同的查询转换。有关在需要时使用此转换的默认 :sql 实现示例,请参阅 metabase.driver.sql.query-processor/preprocess

    您可以在 metabase.query-processor-test.cumulative-aggregation-test 中运行新测试,以验证您的驱动程序实现是否正确。

  • metabase.driver.common/class->base-type 不再支持 Joda Time 类。自 2019 年以来,它们已被弃用。

  • 添加了新功能 :window-functions/offset,以表示驱动程序支持新的 MBQL :offset 子句(相当于 SQL 的 leadlag 函数)。默认情况下,对于 :sql:sql-jdbc 基础的驱动程序启用此功能。其他驱动程序应添加对此子句的实现并启用功能标志。

  • :type/field-values-unsupported 已添加到 metabase.types 命名空间中。它用于字段值计算逻辑,以确定是否应该计算特定字段的字段值。在编写时,这通过 metabase.models.field-values/field-should-have-field-values? 来执行。基于此,驱动程序开发人员有方法为与用于计算的查询不兼容的字段跳过字段值计算。例如,Druid 的 COMPLEX<JSON> 数据库类型字段。请参阅 metabase.driver.druid-jdbcsql-jdbc.sync/database-type->base-type:druid-jdbc 实现,以及 metabase.types 命名空间中的推导,以获取示例。

  • 新增功能 :metadata/key-constraints 已添加,表示驱动程序支持在模式级别定义和强制执行外键约束。这是一个比 :foreign-keys 更为不同、更强的条件。一些数据库(Presto、Athena 等)支持对外键关系进行 查询:foreign-keys),但不在模式中跟踪或强制执行这些关系。在 :sql:sql-jdbc 驱动程序中默认为 true;在第一方 SparkSQL、Presto 和 Athena 驱动程序中设置为 false

  • 新增功能 :connection/multiple-databases 已添加,表示此驱动程序与多个数据库或单个数据库的连接。默认为 false,其中连接指定单个数据库。这是经典关系型数据库(如 Postgres)和一些云数据库的常见情况。相比之下,像 Athena 这样的驱动程序将其设置为 true,因为它连接到 S3 桶,并将其中的每个文件视为数据库。

  • 新增功能 :identifiers-with-spaces 已添加,表示驱动程序支持包含空格字符的标识符,如表或列名。默认为 false

  • 新增功能 :uuid-type 已添加,表示此数据库能够区分和过滤 UUID。只有少数数据库支持本机 UUID 类型。默认为 false

Metabase 0.49.22

  • 新增了一个可选方法 metabase.driver.sql/json-field-length。它应该为所有继承自 :sql 并支持 :nested-field-columns 功能的驱动程序实现。如果实现,Metabase 将在“同步字段”步骤中跳过查询大 JSON 值,否则这可能会减慢嵌套字段列的推理并导致 Metabase 用尽堆空间。

Metabase 0.49.9

  • 已添加另一个驱动功能:upload-with-auto-pk。它仅影响支持uploads的驱动,并且支持它是可选的。默认情况下,驱动支持此功能,如果无法创建具有自增整数列的表,可以选择不支持。驱动可以使用driver/database-supports?来覆盖默认设置。

Metabase 0.49.1

  • 已添加另一个驱动功能:describe-fields。如果驱动选择支持此功能,则必须实现多方法metabase.driver/describe-fields,作为metabase.driver/describe-table的替代。

  • 已添加多方法metabase.driver.sql-jdbc.sync.describe-table/describe-fields-sql。如果驱动支持describe-fields并希望使用metabase.driver/describe-fields的默认JDBC实现,则需要实现此方法。

Metabase 0.49.0

  • 已弃用多方法metabase.driver/describe-table-fks,以支持metabase.driver/describe-fksmetabase.driver/describe-table-fks将在0.52.0版本中删除。

  • 已添加多方法metabase.driver/describe-fks。如果数据库支持:foreign-keys:describe-fks功能,则需要实现此方法。它替代了已弃用的metabase.driver/describe-table-fks方法。

  • 已添加多方法metabase.driver.sql-jdbc.sync.describe-table/describe-fks-sql。如果您想使用metabase.driver/describe-fks的默认JDBC实现,则需要实现此方法。

  • 已添加多方法metabase.driver/alter-columns!。此方法用于在数据库中更改表的列。目前,此功能仅适用于支持:uploads功能的驱动,并为基于JDBC的驱动提供了默认实现。

  • 已添加多方法metabase.driver.sql-jdbc.sync.interface/alter-columns-sql。此方法允许您自定义默认JDBC实现metabase.driver/alter-columns!所使用的查询。

  • 已添加多方法metabase.driver.sql-jdbc.sync.interface/current-user-table-privileges。基于JDBC的驱动可以实现此方法以改善默认SQL JDBC实现metabase.driver/describe-database的性能。如果数据库支持:table-privileges功能且驱动程序是JDBC-based,则需要实现此方法。

  • metabase.driver/create-table!多方法可以接受一个带有可选键primary-key的可选映射。metabase.driver/upload-type->database-type也必须更改,以便如果提供:metabase.upload/auto-incrementing-int-pk作为upload-type参数,则函数应返回不包含主键约束的类型。有关更多信息,请参阅PR #22166。这些更改仅适用于支持:uploads功能的数据库。

  • 已添加多方法metabase.driver/create-auto-pk-with-append-csv?。只有当数据库在47或更早版本中支持:uploads功能时,才需要实现此方法,并且如果支持则返回true。

  • 已添加多方法 metabase.driver/add-columns!。此方法用于向数据库表添加列。只有在数据库支持在47或更早版本中的:uploads功能时,才需要实现此方法。

  • 已添加一个新的驱动方法 metabase.driver/describe-table-indexes 以及一个新的功能 :index-info。此方法用于获取一组索引列或复合索引中的第一列的列名。

  • metabase.util.honeysql-extensions 已在 0.46.0 中弃用,并已删除。使用 Honey SQL 1 的基于 SQL 的驱动程序不再受支持。有关更多信息,请参阅 0.46.0 中的说明。metabase.driver.sql.query-processor/honey-sql-version 现已弃用,不再调用。所有驱动程序都假定使用 Honey SQL 2。

  • 方法 metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type 现已弃用。请改用 metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type-and-value,它具有对 value 的访问权限,因此可以提供更多选择正确转换单位的选择灵活性。

Metabase 0.48.0

  • 现在,在 metabase.mbql.schema 中的 MBQL 架构使用 Malli 而不是 Schema。如果您正在使用此命名空间与 Schema 结合,则需要更新代码以使用 Malli。

  • 已添加另一个驱动程序功能::table-privileges。此功能表示我们是否可以在数据库同步时存储数据库的表级权限。

  • 已添加多方法 metabase.driver/current-user-table-privileges。此方法用于获取数据库连接当前用户拥有的权限集合。如果数据库支持 :table-privileges 功能,则需要实现此方法。

  • 以下在 metabase.query-processor.store (qp.store) 中的函数现已弃用

    • qp.store/database
    • qp.store/table
    • qp.store/field

    更新对 metabase.lib.metadata (lib.metadata) 中相应函数的使用

    (qp.store/database)       => (lib.metadata/database (qp.store/metadata-provider))
    (qp.store/table table-id) => (lib.metadata/table (qp.store/metadata-provider) table-id)
    (qp.store/field field-id) => (lib.metadata/field (qp.store/metadata-provider) field-id)
    

    请注意,新方法返回的键为 kebab-case 而不是 snake_case

  • 类似地,驱动程序不应直接访问应用程序数据库(通过 toucan 函数或其他方式);而是使用 lib.metadata 函数。这种访问可能在未来的版本中受到限制。

  • 实现 metabase.driver.sql.query-processor/->honeysql 以用于 metabase.models.table/Table/:model/Table 的 SQL 驱动程序应更新为使用 :metadata/table 实现。与上述更改一样,主要区别在于新元数据映射使用 kebab-case 键而不是 snake_case 键。

  • metabase.driver.sql.query-processor/cast-field-if-needed 现在期望一个由 lib.metadata/field 返回的 kebab-case 字段。

  • 已删除 metabase.query-processor.store/fetch-and-store-database!metabase.query-processor.store/fetch-and-store-tables!metabase.query-processor.store/fetch-and-store-fields!。现在将根据需要自动获取数据,这些调用不再必要。

  • 已删除 metabase.models.field/json-field?,请使用 metabase.lib.field/json-field? 代替。请注意,新函数接受由 lib.metadata/field 返回的字段,即一个 kebab-case 映射。

  • 测试应尽量避免使用任何 with-temp 辅助函数或应用程序数据库对象;相反,使用上述元数据函数和 metabase.libmetabase.lib.test-utilmetabase.query-processor.test-util 中的辅助 元数据提供者 来模拟它们,例如 mock-metadata-providermetabase-provider-with-cards-for-queriesremap-metadata-providermerged-mock-metadata-provider

  • 现在已弃用 metabase.query-processor.util.add-alias-info/field-reference。如果您的驱动程序实现了它,请实现 metabase.query-processor.util.add-alias-info/field-reference-mlv2 代替。这两个函数之间的唯一区别是后者使用 kebab-case 键传递字段元数据,而前者使用带有 snake_case 键的旧版元数据。

  • 自 0.34 版本以来已弃用的 metabase.driver/current-db-time 以及相关的方法和辅助函数已被删除。请实现 metabase.driver/db-default-timezone 代替。

  • 用于为基于 JDBC 的驱动程序编写 metabase.driver/db-default-timezone 实现的辅助函数 metabase.driver.sql-jdbc.sync.interface/db-default-timezone 已弃用,并将从 0.51.0 或更高版本中删除。您可以轻松实现 metabase.driver/db-default-timezone,并使用 metabase.driver.sql-jdbc.execute/do-with-connection-with-options 获取数据库的 java.sql.Connection

  • 添加了一个新的多方法 metabase.driver.sql.parameters.substitution/align-temporal-unit-with-param-type,它为 fieldparam-type 和给定的驱动程序返回合适的时序单位转换关键字。生成的关键字将用于调用相应的 metabase.driver.sql.query-processor/date 实现来转换 field。如果此 fieldparam-type 组合不需要转换,则返回 nil

  • 已添加多方法 metabase.driver.sql-jdbc.execute/inject-remark。它允许基于 JDBC 的驱动程序覆盖如何将 SQL 查询备注添加到查询中的默认行为(作为注释前缀添加)。

  • 多方法metabase.driver.sql-jdbc.sync.interface/fallback-metadata-query的参数个数已从3个更新为4个,现在它接受一个额外的db参数。新的函数参数为:[driver db-name-or-nil schema table]

Metabase 0.47.0

  • 添加了新的驱动功能::schemas。该功能指示数据库是否在模式(也称为命名空间)中组织表。大多数数据库都有模式,因此此功能默认开启。只有当数据库不存储在模式中的表时,才需要为:schemas实现metabase.driver/database-supports?的多方法。

  • 添加了另一个驱动功能::uploads。该:uploads功能指示数据库是否支持将CSV文件上传到数据库中的表。为了支持上传功能,需要实现以下新的多方法:metabase.driver/create-table!(创建表)、metabase.driver/drop-table!(删除表)和metabase.driver/insert-into!(向表中插入值)。

  • 添加了多方法metabase.driver/syncable-schemas。此方法用于列出可以上传CSV的模式,并且应该包括所有可以同步的模式。目前,只有在数据库有模式且支持:uploads功能时,才需要实现它。

  • 已弃用多方法metabase.driver/supports?,并使用metabase.driver/database-supports?取而代之。现有的默认实现database-supports?目前调用supports?,但在0.50.0版本中将被删除。

  • 已标记多方法metabase.driver.sql-jdbc.execute/connection-with-timezone为弃用,并计划在Metabase 0.50.0版本中删除。新的方法metabase.driver.sql-jdbc.execute/do-with-connection-with-options取代了它。迁移到新方法很简单。有关更多信息,请参阅PR #22166。您应继续使用metabase.driver.sql-jdbc.execute/do-with-connection-with-options而不是clojure.java.jdbc/with-db-connectionclojure.java.jdbc/get-connection

  • 添加了多方法set-role!set-role-statementdefault-database-role。这些方法用于启用连接模拟,这是0.47.0版本中添加的新功能。连接模拟允许用户被分配到在执行任何查询之前设置的特定数据库角色,这样可以在数据库级别而不是(或与)Metabase内置权限系统一起限制对表的访问。

  • 多方法metabase.driver.sql-jdbc.sync.describe-table/get-table-pks已更改为返回向量而不是集合。

  • 函数metabase.query-processor.timezone/report-timezone-id-if-supported已更新,以接受一个额外的database参数,该参数之前有一个参数。此函数可能用于驱动程序多方法的实现。

  • metabase.driver/prettify-native-form 已被添加,以允许驱动开发者使用针对其驱动程序特定的本地格式。有关详细信息,请参阅 PR #34991

Metabase 0.46.0

  • 在 Metabase 0.46.0 中,构建驱动程序的过程略有变化。您的构建命令现在可能看起来像这样

    # Example for building the driver with bash or similar
    
    # switch to the local checkout of the Metabase repo
    cd /path/to/metabase/repo
    
    # get absolute path to the driver project directory
    DRIVER_PATH=`readlink -f ~/sudoku-driver`
    
    # Build driver. See explanation in sample Sudoku driver README
    clojure \
      -Sdeps "{:aliases {:sudoku {:extra-deps {com.metabase/sudoku-driver {:local/root \"$DRIVER_PATH\"}}}}}"  \
      -X:build:sudoku \
      build-drivers.build-driver/build-driver! \
      "{:driver :sudoku, :project-dir \"$DRIVER_PATH\", :target-dir \"$DRIVER_PATH/target\"}"
    

    请参阅我们的示例 Sudoku 驱动的构建说明以了解命令的说明。

    请注意,尽管此命令本身输入量很大,但您现在不再需要在您的驱动程序的 deps.edn 文件中指定 :build 别名。

    请为 https://ask.clojure.net.cn/index.php/7843/allow-specifying-aliases-coordinates-that-point-projects 投票,这将允许我们将来简化驱动程序构建命令。

  • 已添加多方法 metabase.driver/table-rows-sample。该方法用于 Metabase 需要表的一小部分样本的情况,如指纹识别时。在 metabase.db.metadata-queries 命名空间中定义的默认实现通过常规查询处理器运行 MBQL 查询以生成样本行。这在大多数情况下都足够好,因此除非绝对必要,否则不应实现此多方法。目前,唯一使用特殊实现的情况是 BigQuery,因为它不尊重限制子句。

  • 已添加多方法 metabase.driver.sql.query-processor/datetime-diff。该方法由 ->honeysql 的实现用于 :datetime-diff 子句。如果您想使用默认的 SQL 实现 ->honeysql:datetime-diff,其中包含对所有单位的参数类型验证,则建议实现此方法。

  • 已添加多方法 metabase.query-processor.util.add-alias-info/field-reference。该方法用于通过 add-alias-info 中间件生成字段的引用。(注意,此中间件是可选的,目前它仅由 SQL 和 MongoDB 驱动程序使用。)默认实现返回字段实例的名称。如果仅名称不是一个有效的引用,则应该覆盖它。例如,MongoDB 支持嵌套文档和嵌套字段的引用,应包含整个路径。请参阅 metabase.driver.mongo.query-processor 命名空间以获取替代实现。

  • 已在 0.43.0 中弃用的多方法 metabase.driver.sql-jdbc.sync.interface/syncable-schemas(别名为 metabase.driver.sql-jdbc.sync/syncable-schemas)已被删除。请实现 metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas 代替。有关更多详细信息,请参阅下面的 0.43.0 注释。

  • 已在 0.42.0 中弃用的多方法 metabase.driver/format-custom-field-name 已被删除。请实现 metabase.driver/escape-alias 代替。有关更多信息,请参阅下面的 0.42.0 注释。

  • 已在 0.35.0 中弃用的多方法 metabase.driver.sql-jdbc.execute/read-column 已被删除。请实现 metabase.driver.sql-jdbc.execute/read-column-thunk 代替。有关更多信息,请参阅下面的 0.35.0 注释。

Honey SQL 2

以下内容仅适用于SQL驱动程序;对于非SQL驱动程序,您可以忽略。

在Metabase 0.46.0之前,SQL驱动程序在编译查询时使用Honey SQL 1作为中间目标。在0.46.0版本中,我们开始迁移到Honey SQL 2作为我们的新中间目标。

我们计划继续支持使用Honey SQL 1,直到Metabase 0.49.0。请务必在此之前迁移您的驱动程序。

在Metabase 0.46.x、0.47.x和0.48.x版本中,您可以通过实现metabase.driver.sql.query-processor/honey-sql-version多态方法来指定驱动程序应使用的Honey SQL版本。

(require '[metabase.driver.sql.query-processor :as sql.qp])

;;; use Honey SQL 2 for :my-driver
(defmethod sql.qp/honey-sql-version :my-driver
  [_driver]
  2)

此方法必须返回12。目前,默认实现返回1。实际上,这意味着您目前必须选择加入Honey SQL 2编译。最好是尽早这样做,以便您的驱动程序为0.49.0提前做好准备。

在Metabase 0.47.x或0.48.x版本中,我们可能会将默认的Honey SQL版本更改为2,以确保每个人都能意识到0.49.0即将到来的破坏性更改,并给他们一个或两个发布周期来更新他们的驱动程序以针对Honey SQL 2。您仍然可以通过实现sql.qp/honey-sql-version并返回1来选择加入使用Honey SQL 1,直到0.49.0。

需要更改的内容

我们的Honey SQL实用程序命名空间metabase.util.honeysql-extensions,通常别名为hx,已更新为生成适用于Honey SQL 1或Honey SQL 2的适当形式。这是根据您的驱动程序的honey-sql-version自动完成的。metabase.driver.sql.query-processor本身也以相同的方式支持这两个目标。

您将需要更改驱动程序代码的实际更改可能相当小。在移植驱动程序时需要注意的最重要的事情

  1. 避免使用来自Honey SQL 1命名空间的东西,如honeysql.corehoneysql.format。如果您必须,请使用Honey SQL honey.sql;您可能不需要这两者。

  2. 尽管您可以在短期内继续使用metabase.util.honeysql-extensions,因为它可以针对Honey SQL的任何版本,但我们可能会在未来的某个时刻删除此命名空间。更新您的代码以使用metabase.util.honey-sql-2代替。这些命名空间实现了一套几乎相同的辅助函数,因此您只需更改在您的ns形式中:require的是哪一个即可。

  3. honeysql.core/call 已不存在;现在不再使用类似 (hsql/call :my_function 1 2) 的形式,而是直接返回一个普通向量,如 [:my_function 1 2](hsql/raw "x") 现在是 [:raw "x"]。可以使用 honey.sql/register-fn! 在 Honey SQL 2 中注册新的处理器。不存在 Honey SQL 1 的 honeysql.format./ToSql 协议的等效功能,因此您不再需要定义一次性类型来实现自定义 SQL 编译规则。请使用 honey.sql/register-fn! 代替。

  4. Honey SQL 1 中,您可以通过实现多方法 honeysql.format/fn-handler 来在一定程度上注册函数。Metabase 以这种方式注册了函数 :extract:distinct-count:percentile-cont。对于 Honey SQL 2,我们已经将这些函数注册为 metabase.util.honey-sql-2 命名空间中的限定关键字,以避免混淆它们在何处定义。因此,如果您使用这些函数,则需要更新关键字。

    ;;; Honey SQL 1
    (hsql/call :distinct-count expr)
    

    变为

    ;;; Honey SQL 2
    (require '[metabase.util.honey-sql-2 :as h2x])
    
    [::h2x/distinct-count expr]
    
  5. 因为自定义表达式现在是类似 [:my_function 1] 的普通向量,所以如果它们出现在 :select:from 或其他可能被解释为 [expression alias] 的向量位置时,可能需要将表达式包装在额外的向量中。例如。

    ;; Honey SQL 1
    (honeysql.core/format {:select [[:my_function 1]]})
    ;; => ["SELECT my_function AS 1"]
    
    ;; Honey SQL 2
    ;;
    ;; WRONG
    (honey.sql/format {:select [[:my_function 1]]})
    ;; => ["SELECT my_function AS ?" 1]
    
    ;; CORRECT
    (honey.sql/format {:select [[[:my_function 1]]]})
    ;; => ["SELECT MY_FUNCTION(?)" 1]
    

    SQL 查询处理器会自动为此生成形式,因此您只需要担心覆盖它生成 :select 或其他顶层子句的方式。

  6. 数字默认是参数化的,例如 {:select [1]} 变为 SELECT ? 而不是 SELECT 1。您可以使用 :inline 强制生成内联 SQL:{:select [[[:inline 1]]]} 变为 SELECT 1。SQL 查询处理器代码生成的数字应自动内联,但您可能需要确保生成的任何数字都包装在 :inline 中,如果它们可能成为 GROUP BY 子句中的表达式。某些数据库只能在表达式未被参数化时将其视为相同的内容。

    -- This is okay
    SELECT x + 1
    FROM table
    GROUP BY x + 1
    
    -- Bad: DB doesn't know whether the two x + ? expressions are the same thing
    SELECT x + ?
    FROM table
    GROUP BY x + ?
    

:inline 时请谨慎操作——小心不要在不信任的字符串或其他可能导致 SQL 注入的地方使用它。只有内联 number? 才是安全的。

有关库版本之间差异的更多信息,请参阅 Honey SQL 1.x 与 2.x 的差异

注意:希望这些破坏性更改在 0.46.0 发布之前得到解决。如果有变化,将会更新。

metabase.util.honeysql_extensions.Identifermetabase.util.honeysql_extensions.TypedHoneySQLForm 分别已移动到 metabase.util.honey_sql_1.Identifermetabase.util.honey_sql_1.TypedHoneySQLForm。如果您直接引用这些类名,您可能需要更新以使用新的类名。

同样,metabase.util.honeysql-extensions/->AtTimeZone 已被删除;请使用 metabase.util.honeysql-extensions/at-time-zone 代替。

Metabase 0.45.0

  • metabase.driver.sql-jdbc.connection/details->connection-spec-for-testing-connection 在 Metabase 0.45.0 中已被移除,因为它会泄露 SSH 隧道。请参阅 #24445。如果您使用此功能,请更新您的代码以使用 metabase.driver.sql-jdbc.connection/with-connection-spec-for-testing-connection 代替,它会在自己之后正确地清理。

新方法

  • metabase.driver.sql-jdbc.sync.describe-table-fields 已被添加。如果您想覆盖获取表字段元数据(如类型)的默认行为,请实现此方法。

  • metabase.driver.sql-jdbc.sync.describe-table/get-table-pks 已被添加。此方法用于根据表获取一组主键。

  • ->honeysql [<driver> :convert-timezone] 已被添加。如果您想使您的驱动程序支持 convertTimezone 表达式,请实现此方法。此方法接受 2 或 3 个参数,并返回一个 无时区的时间戳 列。

Metabase 0.43.0

  • MBQL 查询中的 :expressions 映射现在使用字符串作为键而不是关键字(请参阅 #14647)。只有当您直接访问或操作此映射时,您才需要关注此问题。实现 ->honeysql:sql 衍生驱动程序(包括 :sql-jdbc)可能需要更新。自 Metabase 0.35.0 起已提供实用函数 metabase.mbql.util/expression-with-name,它可以处理两种类型的键。强烈建议您使用此函数而不是直接访问 :expressions,因为这样做可以使您的驱动程序与 0.42.0 和 0.43.0 及更高版本兼容。

  • 现在在 sql-jdbc.sync 命名空间下有一个 describe-nested-field-columns 方法,它返回 NestedFCMetadata 的实例。这是为了允许在 Postgres 中使用 JSON 列,以及其他通常是普通的关系型数据库,但有时它们有具有 JSON 或其他语义的反规范化列。给定一个具有嵌套字段语义的表(即类型化的子字段仍然是反规范化的,但在行之间类型稳定),返回值应为 NestedFCMetadata,这是一个将扁平化键路径映射到检测到的子字段的映射。在同步时,字段检测将丰富这些嵌套类型。这与我们对 mongo 的处理方式有很大不同,因为每种 JSON 列都是不同的,但它将在每次同步时运行,因此它不能太慢,即使在巨大的表和这些巨大表上的巨大反规范化列中也是如此。

Metabase 0.42.0

Metabase 0.42.0 中的更改会影响派生于 :sql 的驱动程序(包括 :sql-jdbc)。非 SQL 驱动程序可能不需要更改。

0.42.0 引入了对 SQL 查询处理器编译 MBQL :field 子句以及确定别名的几种重大更改。有关更多背景信息,请参阅拉取请求 #19384

如果您正在处理字段或表别名,我们合并了大量重叠的变量和方法,这意味着您可能需要删除已弃用的方法实现。

重大更改

  • 字段实例的 metabase.driver.sql.query-processor/->honeysql 方法,例如

    (defmethod sql.qp/->honeysql [:my-driver (class Field)]
      [driver field]
      ...)
    

    不再调用。所有编译现在都由 MBQL :field 子句方法处理,例如

    (defmethod sql.qp/->honeysql [:my-driver :field]
      [driver field-clause]
      ...)
    

    如果您在这里执行了特殊操作,您需要将此特殊逻辑移动到 [<driver> :field] 中。 (您可能不再需要此特殊逻辑 - 请参阅以下内容。)

  • :field:expression:aggregation-options 子句现在包含有关您应在 SQL AS 的左侧和右侧或其他查询位置引用它们时应使用的别名信息。有关新信息的详细讨论,请参阅 PR #19610,以下称为/#19610 信息

  • 如果您为 :field(class Field) 实现了自定义的 ->honeysql,则 :field->honeysql 方法应使用或替换 #19610 信息,而不是尝试以其他方式确定或覆盖它。

新方法

  • metabase.driver/escape-alias(从 0.41.0 中引入的 metabase.driver.sql.query-processor/escape-alias 移动而来)现在用于生成 #19610 信息 并在 SQL QP 代码中保持一致。如果您需要出于任何原因(例如,转义不允许的字符)转换生成的字段别名,请实现此方法。

  • 已添加 metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas,最终将替换 metabase.driver.sql-jdbc.sync.interface/syncable-schemas。它具有类似的目的,但它还传递了包含和排除模式(例如,auth*,data*),以进一步过滤要同步的模式。

弃用方法和变量

以下方法和变量计划在 Metabase 0.45.0 中删除,除非另有说明。

  • metabase.driver/format-custom-field-name 现在不再使用。请实现 metabase.driver/escape-alias 代替。

  • metabase.driver.sql.query-processor/escape-alias 已重命名为 metabase.driver/escape-alias。其他内容保持不变。

  • metabase.driver.sql.query-processor/field-clause->alias 现在不再使用可选参数 unique-name-fn。别名现在在转义后自动生成唯一值;如果需要在它们变得唯一之前执行特殊操作,请实现 metabase.driver/escape-alias。如果需要执行非常特殊的操作,唯一的别名还会再次转义。(如果需要出于任何原因转义别名,请使用 #19610 信息。)此方法仍在 Metabase 0.44.0 中计划删除。

  • metabase.driver.sql.query-processor/field->alias(在 0.41.0 中已弃用)在 0.42.0 中不再使用。实现此方法不再产生任何效果。如果需要执行特殊操作,请使用 metabase.driver/escape-alias 代替;如果需要出于任何原因转义别名,请使用 #19610 信息。此方法仍在 Metabase 0.44.0 中计划删除。

  • metabase.driver.sql.query-processor/*field-options* 现在不再使用,并且不再自动绑定。如果需要出于任何原因字段选项,请参阅我们的 SQL Server 驱动程序,了解如何创建它的示例。

  • metabase.driver.sql.query-processor/*table-alias* 现在不再使用,并且不再自动绑定。请使用或覆盖 :metabase.query-processor.util.add-alias-info/source-table(来自 #19610 信息)。

  • metabase.driver.sql.query-processor/*source-query* 现在不再使用,并且不再自动绑定。请使用 metabase.driver.sql.query-processor/*inner-query* 代替,它始终绑定,即使我们不在源查询中。

  • metabase.driver.sql.query-processor/field->identifier 现已不再使用。在任何情况下,实现此方法都不再是必要的。若需要在此处执行特殊操作,请覆盖 ->honeysql[<driver> :field] 并操作 #19610 信息

  • metabase.driver.sql.query-processor/prefix-field-alias 已不再使用。之前,它是为了给驱动程序提供机会来自动转义连接字段的自动生成的别名。这不再是必要的,因为 metabase.driver/escape-alias 会自动调用生成的别名。若需要执行特殊操作,请实现 metabase.driver/escape-alias
  • metabase.driver.sql-jdbc.sync.interface/syncable-schemas 已被弃用,改为使用 metabase.driver.sql-jdbc.sync.interface/filtered-syncable-schemas(见上文)。现有的 syncable-schemas 默认实现目前调用 filtered-syncable-schemas(带有 nil 过滤器,即过滤操作实际上是空操作),但它最终将被移除。

已移除的方法和变量

  • metabase.mbql.schema/DatetimeFieldUnit 已在 0.39.0 中弃用,现已被移除。

旧版本

在 0.42.0 之前,此信息在我们的维基页面上跟踪。您可以在下表中找到 0.42.0 之前版本的更改

版本 维基页面
0.41.0 更改
0.40.0 无更改。
0.39.0 无更改。
0.38.0 更改
0.37.0 更改
0.36.0 更改
0.35.0 更改

阅读其他 Metabase 版本的文档

想改进这些文档? 提出更改。