无法在Rails测试环境中使用TimescaleDB

2023-12-29

我被困在 Rails 中使用 TimescaleDB - 开发中一切正常,但在我的测试套件中我无法插入任何数据。

我尝试过的

A) 使用 SQL 模式转储

这导致了我看到的原始错误消息。它确实为 TimescaleDB 创建了部分架构,但不是全部。我有一个超表,但它无法正常工作

B) 使用 Ruby 架构转储

这让我可以插入到我的表中,但它根本不是超表 - ruby​​ 语法丢失了与 TimescaleDB 和超表相关的所有内容。

C) 直接迁移测试数据库

我尝试避免 schema.struct 转储并加载以下内容:

$ rails db:drop
Dropped database 'my_app_development'
Dropped database 'my_app_test'
$ RAILS_ENV=test rails db:create
Created database 'my_app_test'
$ RAILS_ENV=test rails db:migrate
== 20200517164444 EnableTimescaledbExtension: migrating =======================
-- enable_extension("timescaledb")
WARNING:  
WELCOME TO
 _____ _                               _     ____________  
|_   _(_)                             | |    |  _  \ ___ \ 
  | |  _ _ __ ___   ___  ___  ___ __ _| | ___| | | | |_/ / 
  | | | |  _ ` _ \ / _ \/ __|/ __/ _` | |/ _ \ | | | ___ \ 
  | | | | | | | | |  __/\__ \ (_| (_| | |  __/ |/ /| |_/ /
  |_| |_|_| |_| |_|\___||___/\___\__,_|_|\___|___/ \____/
               Running version 1.7.0
For more information on TimescaleDB, please visit the following links:

 1. Getting started: https://docs.timescale.com/getting-started
 2. API reference documentation: https://docs.timescale.com/api
 3. How TimescaleDB is designed: https://docs.timescale.com/introduction/architecture

Note: TimescaleDB collects anonymous reports to better understand and assist our users.
For more information and how to disable, please see our docs https://docs.timescaledb.com/using-timescaledb/telemetry.

   -> 0.2315s
== 20200517164444 EnableTimescaledbExtension: migrated (0.2316s) ==============

== 20200517165027 CreateAccounts: migrating ===================================
-- create_table(:accounts)
   -> 0.0095s
== 20200517165027 CreateAccounts: migrated (0.0095s) ==========================

== 20200517165103 CreateMetrics: migrating ====================================
-- create_table(:metrics)
   -> 0.0116s
== 20200517165103 CreateMetrics: migrated (0.0117s) ===========================

== 20200517170842 CreateEvents: migrating =====================================
-- create_table(:events)
   -> 0.0072s
-- remove_column(:events, :id)
   -> 0.0020s
-- execute("SELECT create_hypertable('events', 'time');\n")
   -> 0.0047s
== 20200517170842 CreateEvents: migrated (0.0142s) ============================

pg_dump: warning: there are circular foreign-key constraints on this table:
pg_dump:   hypertable
pg_dump: You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.
pg_dump: Consider using a full dump instead of a --data-only dump to avoid this problem.
pg_dump: warning: there are circular foreign-key constraints on this table:
pg_dump:   chunk
pg_dump: You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.
pg_dump: Consider using a full dump instead of a --data-only dump to avoid this problem.

但是当运行测试套件时,它与尝试 A 相同。

在实际打印此消息几次后运行测试,这让我认为 Rails 会自动神奇地使用structure.sql再次重新创建测试数据库:


psql:/home/axel/src/my_app/db/structure.sql:16: WARNING:  
WELCOME TO
 _____ _                               _     ____________  
|_   _(_)                             | |    |  _  \ ___ \ 
  | |  _ _ __ ___   ___  ___  ___ __ _| | ___| | | | |_/ / 
  | | | |  _ ` _ \ / _ \/ __|/ __/ _` | |/ _ \ | | | ___ \ 
  | | | | | | | | |  __/\__ \ (_| (_| | |  __/ |/ /| |_/ /
  |_| |_|_| |_| |_|\___||___/\___\__,_|_|\___|___/ \____/
               Running version 1.7.0
For more information on TimescaleDB, please visit the following links:

 1. Getting started: https://docs.timescale.com/getting-started
 2. API reference documentation: https://docs.timescale.com/api
 3. How TimescaleDB is designed: https://docs.timescale.com/introduction/architecture

Note: TimescaleDB collects anonymous reports to better understand and assist our users.
For more information and how to disable, please see our docs https://docs.timescaledb.com/using-timescaledb/telemetry.

错误信息

$ rails test
Running via Spring preloader in process 107937
Run options: --seed 29840

# Running:

E

Error:
Api::EventsControllerTest#test_POST_event_data_-_new_metric:
DRb::DRbRemoteError: PG::FeatureNotSupported: ERROR:  invalid INSERT on the root table of hypertable "events"
HINT:  Make sure the TimescaleDB extension has been preloaded.
 (ActiveRecord::StatementInvalid)
    app/controllers/api/events_controller.rb:5:in `create'
    test/controllers/api/events_controller_test.rb:9:in `block in <class:EventsControllerTest>'


rails test test/controllers/api/events_controller_test.rb:8



Finished in 0.215286s, 4.6450 runs/s, 0.0000 assertions/s.
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

我感觉这与 Rails 如何使用创建测试数据库有关schema.rb(对于默认的config.active_record.schema_format = :ruby) or structure.sql (for config.active_record.schema_format = :sql。 我已经尝试了结构的 Ruby 和 SQL 设置,但都不起作用 - 开发数据库已正确迁移,但测试数据库未正确设置。

在下面的两个数据库(开发和测试)中,我们可以看到唯一的区别是测试数据库丢失了:Child tables: _timescaledb_internal._hyper_1_1_chunk

开发数据库

$ psql -d my_app_development
psql (12.2)
Type "help" for help.

my_app_development=# SHOW shared_preload_libraries;
 shared_preload_libraries 
--------------------------
 timescaledb
(1 row)

my_app_development=# insert into events (metric_id, time, value) VALUES (1, NOW(), 22);
INSERT 0 1
my_app_development=# \d+ events
                                              Table "public.events"
  Column   |            Type             | Collation | Nullable | Default | Storage | Stats target | Description 
-----------+-----------------------------+-----------+----------+---------+---------+--------------+-------------
 metric_id | bigint                      |           |          |         | plain   |              | 
 time      | timestamp without time zone |           | not null |         | plain   |              | 
 value     | numeric                     |           |          |         | main    |              | 
Indexes:
    "events_time_idx" btree ("time" DESC)
Triggers:
    ts_insert_blocker BEFORE INSERT ON events FOR EACH ROW EXECUTE FUNCTION _timescaledb_internal.insert_blocker()
Child tables: _timescaledb_internal._hyper_1_1_chunk
Access method: heap

Test DB

$ psql -d my_app_test
psql (12.2)
Type "help" for help.

my_app_test=# SHOW shared_preload_libraries;
 shared_preload_libraries 
--------------------------
 timescaledb
(1 row)

my_app_test=# insert into events (metric_id, time, value) VALUES (1, NOW(), 22);
ERROR:  invalid INSERT on the root table of hypertable "events"
HINT:  Make sure the TimescaleDB extension has been preloaded.
my_app_test=# \d+ events
                                              Table "public.events"
  Column   |            Type             | Collation | Nullable | Default | Storage | Stats target | Description 
-----------+-----------------------------+-----------+----------+---------+---------+--------------+-------------
 metric_id | bigint                      |           |          |         | plain   |              | 
 time      | timestamp without time zone |           | not null |         | plain   |              | 
 value     | numeric                     |           |          |         | main    |              | 
Indexes:
    "events_time_idx" btree ("time" DESC)
Triggers:
    ts_insert_blocker BEFORE INSERT ON events FOR EACH ROW EXECUTE FUNCTION _timescaledb_internal.insert_blocker()
Access method: heap

具有 SQL 架构的 ActiveRecord

CREATE EXTENSION IF NOT EXISTS timescaledb WITH SCHEMA public;

SET default_tablespace = '';

SET default_table_access_method = heap;

CREATE TABLE public.events (
    metric_id bigint,
    "time" timestamp without time zone NOT NULL,
    value numeric
);

CREATE INDEX events_time_idx ON public.events USING btree ("time" DESC);

CREATE TRIGGER ts_insert_blocker BEFORE INSERT ON public.events FOR EACH ROW EXECUTE FUNCTION _timescaledb_internal.insert_blocker();

带有 Ruby 模式的 ActiveRecord

ActiveRecord::Schema.define(version: 2020_05_17_170842) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"
  enable_extension "timescaledb"

  create_table "events", id: false, force: :cascade do |t|
    t.bigint "metric_id"
    t.datetime "time", null: false
    t.decimal "value"
    t.index ["time"], name: "events_time_idx", order: :desc
  end
end

注意:这会丢失ts_insert_blocker触发器并让我插入events表,但它不再是超表:


my_app_test=# \d+ events
                                              Table "public.events"
  Column   |            Type             | Collation | Nullable | Default | Storage | Stats target | Description 
-----------+-----------------------------+-----------+----------+---------+---------+--------------+-------------
 metric_id | bigint                      |           |          |         | plain   |              | 
 time      | timestamp without time zone |           | not null |         | plain   |              | 
 value     | numeric                     |           |          |         | main    |              | 
Indexes:
    "events_time_idx" btree ("time" DESC)
Access method: heap

附加信息

相关问题:使用 Rails 4.2 针对 TimescaleDB 数据库运行 RSpec 测试套件 https://stackoverflow.com/questions/59141045/running-an-rspec-test-suite-against-a-timescaledb-database-with-rails-4-2- 这些建议对我不起作用,并且没有可接受的答案。

版本信息:

  • 导轨 6.0.3
  • Postgres 12.2
  • 时间刻度数据库 1.7.0

Edit 1

我将以下内容添加到我的test/test_helper.rb类似于@cstabru提到的解决方法

def execute_create_hypertable(sql)
  ActiveRecord::Base.connection.execute(sql)
rescue ActiveRecord::StatementInvalid => e
  raise e unless e.message.include? 'is already a hypertable'
end

execute_create_hypertable <<~SQL
  SELECT create_hypertable('events', 'time');
SQL

但也许我们可以使用类似的东西SELECT create_hypertable('hypertable_name', 'time_field', if_not_exists => TRUE在初始化程序中而不是在数据库迁移中创建超表?


我也遇到了这个问题,无论我以哪种方式重新创建数据库模式(sql 或 ruby​​ 格式),都不会重新创建超级表,因为未导出时间刻度内部模式数据。

注意到当我使用sql格式,它复制ts_insert_blocker触发器确实会因此错误而中断表上的插入(我相信是由于触发器功能不可用)

PG::FeatureNotSupported: ERROR:  invalid INSERT on the root table of hypertable "hypertable_name"
HINT:  Make sure the TimescaleDB extension has been preloaded.

要解决根本问题(sql 或 ruby​​ 格式),我们可以通过以下方式手动重新创建超表(并删除触发器)

DROP TRIGGER IF EXISTS ts_insert_blocker ON events;
DROP TRIGGER

SELECT create_hypertable('hypertable_name', 'time_field', if_not_exists => TRUE);
....
(1 row)

现在手动检查超表是否存在,因为https://github.com/timescale/timescaledb/pull/862 https://github.com/timescale/timescaledb/pull/862

SELECT * FROM timescaledb_information.hypertable;

我已将这些 DDL 命令添加到我的spec_helper.rb确保测试数据库使用实际的超表。我想确保测试数据库架构反映我的生产/暂存设置。

config.before(:suite) do
  # ensure the hypertable_name hypertable is setup correctly
  ActiveRecord::Base.connection.execute(
    "DROP TRIGGER IF EXISTS ts_insert_blocker ON hypertable_name;"
  )
  ActiveRecord::Base.connection.execute(
    "SELECT create_hypertable('hypertable_name', 'time_field', if_not_exists => TRUE);"
  )
  has_hypertables_sql = "SELECT * FROM timescaledb_information.hypertable WHERE table_name = 'hypertable_name';"
  if ActiveRecord::Base.connection.execute(has_hypertables_sql).to_a.empty?
    raise "TimescaleDB missing hypertable on 'hypertable_name' table"
  end
end

如果人们觉得这很有用,我可以考虑提取到 gem 来帮助 Rails 环境的模式恢复,https://github.com/timescale/timescaledb/issues/1916 https://github.com/timescale/timescaledb/issues/1916

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法在Rails测试环境中使用TimescaleDB 的相关文章

  • Rails:自动加载库不起作用

    由于某种原因我的自动加载器无法工作 我遵循了一些教程 这是我的 config application rb 文件的样子 require File expand path boot FILE require rails all Bundler
  • Rails 路线、url 和子域

    我的 ruby 应用程序分为不同的命名空间 例如 免费 free domain com 专业版 pro domain com vip vip domain com 在路由文件中看起来像这样 namespace free do match h
  • 两种模型,一种是 STI,一种是验证

    假设我有两个表 产品和订单 为了简单起见 假设一次只能购买一种产品 因此没有像 order items 这样的连接表 所以关系是Product有很多订单 Order属于product 因此 product id是Order表中的一个fk 产
  • 在 cygwin 和 powershell 中查看不同的 gem 列表

    我用的是gem listpowershell 和 cygwin 中的命令都显示不同的 gem 列表 Cygwin 显示 LOCAL GEMS bundler 1 2 3 json 1 7 5 minitest 2 12 1 rake 0 9
  • 如何在 Rails 中格式化日期时间?

    在我的 Rails 视图中 我有以下显示日期时间的代码 该行的结果如下 2013 02 02 01 00 00 UTC 我该如何更改它 使其显示为 2 2 13 X 00 PST 使用红宝石的strftime 关于日期 日期时间 看一下文档
  • 如何在Rails中管理没有id的表?

    我有两个模型 人模型和关系模型 第二个存储有关两个人之间关系的信息 它有parent id和child id字段 但没有id字段 我将它与 has many through 连接起来并且它有效 But 即使表中存在某些关系 因为没有 id
  • .where 与 find。 ActiveRecord::Relation NoMethodError

    我是 Rails 新手 这似乎很明显 但找不到答案 当我做 u User where email email string u name new name 不起作用 我不断收到 NoMethodError undefined method
  • Jquery 条件适用于除 safari 之外的所有浏览器

    在 iPhone 和 iPad 上的 Safari 中 我为条件语句设置的选择器不起作用 并且会导致每个 ajax 请求出现重复的内容 它在 android chrome firefox ie 和桌面版 safari 上运行良好 li mi
  • Rails 3 应用程序的 MySQL Cluster (NDB) 与 MySQL Replication (InnoDB):优点/缺点?

    我们正在对当前系统进行概述 试图找出是否可以提高性能和可靠性 目前 我们运行着一堆内部 Rails 应用程序和基于 Rails 的网站 有些已经是 Rails 3 有些正在转换为 Rails 3 它们都连接到以下 MySQL 设置 mysq
  • 未使用 form_with 显示时出错

    早上好 我正在按照教程进行操作http edgeguides rubyonrails org getting started html http edgeguides rubyonrails org getting started html
  • 回形针:从带扩展名的 url 上传

    我想通过 S3 存储上的回形针从 URL 上传图片 我与 Ruby 1 9 3 Rails 3 2 6 paperclip 3 1 3 aws sdk 1 3 9 我有我的图片模型 class Asset has attached file
  • 如何在Rails 4.1中使用secrets.yml作为API_KEYS?

    在我最近的一个项目中 我开始于 gitignoring包含机密和环境变量的文件 因此 除了包含第三方机密 例如 Stripe Twitter API 或 Facebook Graph 或内部 api keys 等 的文件外 整个项目都致力于
  • Active Record 和 DAO 之间的区别?

    数据访问对象和 Active Record 之间有什么区别 它们看起来非常相似 因为都在应用程序和持久层之间构建了一个层 并使用 SQL 查询抽象出直接数据库访问 数据访问对象 DAO 是指数据层中负责在域中保存单独实体的对象 Active
  • 在关联声明中使用“self”(:has_many,:has_one)

    我需要在 has many 声明中引用模型的自身 我有一门课 我们称之为 Foo Foo has many 酒吧 Foo 有一个名为 randomize 的布尔属性 它确定 has many 关系中 Bar 的顺序 如果 randomize
  • 在所有延迟的作业之前挂钩

    是否可以在所有delayed job任务之前运行一个方法 基本上 我们试图确保每台运行delayed job的服务器都有我们代码的最新实例 因此我们希望运行一个方法来在每个作业运行之前检查这一点 我们已经有了 check 方法并在其他地方使
  • 包括 collection_select 帮助程序的空白和默认值

    我希望在 Rails 应用程序的下拉列表中有一个 选择一个选项 选项 我正在使用collection select辅助标签 它看起来像这样 我希望下拉菜单的默认选项是 选择国家 地区 Use the include blank option
  • 表单元素的自定义 HTML 错误包装器

    我想找到一种方法来自定义默认错误html div class field with errors div 参加我自己的课程 div class clearfix error div
  • Rails 上的 SASS 无效 CSS 错误

    我正在尝试使用http startbootstrap com stylish portfolio http startbootstrap com stylish portfolio但是 在我的 Rails 应用程序中 我在 vintage
  • Rails:将参数从视图传递到控制器

    我在 Rails 中有以下模型 class Task lt ActiveRecord Base attr accessible description name project belongs to project validates na
  • 使用 PostgreSQL 的模式和 Rails 创建多租户应用程序

    我已经想通的事情 我正在学习如何在 Rails 中创建多租户应用程序 该应用程序根据用于查看应用程序的域或子域来提供来自不同模式的数据 我已经回答了一些问题 如何让 subdomain fu 也能与域一起使用 这是有人问了同样的问题 htt

随机推荐

  • C++ 投掷类成员

    我有以下 C 代码 template
  • 查找数组中的重复元素?

    我看到一个面试题是这样的 数组中有一个数字重复 找到它 简单的解决方案如下 for int i 0 i
  • REST API 的试运行策略

    我正在寻找 REST API 的 试运行 操作的一些最佳实践 假设我有一个端点将资金从账户 A 转账到账户 B 我可以像这样发起转账 POST transactions amount 1000 how much to transfer so
  • jQuery 数据绑定 - 现在流行的插件是什么?

    我需要某种类型的 JS MVC DataBinding 解决方案 与实施 GMAIL Web 应用程序类似 消息索引和消息显示 在消息显示的位置 如果您修改消息 它会自动在消息索引中更新 我应该学习什么插件才能在不使用大量 jQuery 的
  • Tensorflow 中的入队和增量变量

    如何使张量流图将递 增的数字推送到队列 我这样做只是为了学习目的 所以我希望您保持它与我正在做的事情相似 并纠正我做错的事情 这是我的代码 import tensorflow as tf create queue queue tf Rand
  • 通过 attr_accessor 对模型对象进行排序

    当我必须对对象列表进行排序时 我认为 attr accessor 具有与另一个相同的行为 但似乎有所不同 dataRecords MyData where day Time now yesterday strftime Y m d to i
  • 仅禁用自动生成的表单上的特定“绿色加号”图标

    如何在自动生成的表单中禁用特定 manytomany 或 foreignkey 字段上的绿色图标 使用CSS如下 add another display none 禁用所有我不想要的 一个例子是工作日模型 存储从星期一到星期日的天数 指向该
  • Python 的多处理和内存

    我在用multiprocessing imap unordered对值列表执行计算 def process parallel fnc some list pool multiprocessing Pool for result in poo
  • 来自 Cordova iOS 插件的后续回调不会触发

    我在从 cordova 插件 iOS 插件 立即触发后续回调时遇到麻烦 在 XCode 调试器中 我清楚地看到它跳过了 self commandDelegate sendPluginResult pluginResult callbackI
  • ORA-01036: 通过 C# 运行查询时非法变量名称/编号

    我正在尝试使用ALTER USER在以下代码中 使用 C 中的 OracleCommand 查询 Oracle 数据库 如果用户名和密码的值不是空字符串 它将创建查询 但我收到一个错误 ORA 01036 illegal variable
  • 与带有分隔符的 String.Split 相反 (.net)

    有没有办法做相反的事情String Split在 Net 中 也就是说 用给定的分隔符组合数组的所有元素 Taking a b c 和给予 a b c 带有分隔符 UPDATE 我自己找到了答案 它是String Join method 找
  • 从 MS Excel 访问 Redis?

    我想使用 Redis 从命令行 脚本 Web 和电子表格中查询数据 除了电子表格之外 我可以找到很好的例子 不过 我不太知道从哪里开始访问 MS Excel 电子表格 谷歌让我失望了 请让我知道您建议如何执行此操作 谢谢 附注对于那些不熟悉
  • Spring MVC 请求映射

    我正处于学习使用 Spring MVC 的早期阶段 我创建了一个控制器并应用了RequestMapping对其进行注释 当我运行该项目时 索引页面按预期显示index htm 但是当我导航到应该指向我的控制器的 URI 时 我收到 404
  • 使用 HttpModule 进行本地化安全吗?

    我正在考虑使用 HttpModule 进行本地化 基于中的示例 本文 http weblogs manas com ar smedina 2008 12 17 internationalization in aspnet mvc 但我很好奇
  • Boost Beast 异步 Websocket 服务器 如何与会话交互?

    所以我不知道为什么 但我无法理解 boost Beast websocket 服务器以及如何 或应该 与其交互 我制作的基本程序看起来像这样 跨 2 个类 WebSocketListener and WebSocketSession htt
  • Java(Web 服务 - SOAP)- 如何在客户端添加 SOAP 处理程序并正确启用 MTOM?

    Java JDK 1 6 0 7 WSGEN 版本 JAX WS RI 2 2 3 b01 我有以下问题 SOAPBinding binding SOAPBinding BindingProvider port getBinding bin
  • 是否可以在 GitHub 上搜索特定文件名?

    我知道 GitHub Web 界面可让您在所有存储库中搜索具有特定路径名的文件 例如搜索path app models user rb产生 gt 109k 结果 但是有没有一种方法可以在所有存储库中搜索独立于其子目录位置的文件名 我尝试在中
  • 查看文件是否为空[重复]

    这个问题在这里已经有答案了 可能的重复 在 Windows 上用 Java 检查文件是否为空的最有效方法 https stackoverflow com questions 7190618 most efficient way to che
  • Gradle 测试任务不运行带有 @Category 和 @RunWith 注释的 JUnit 测试

    Gradle 不使用 Category 和 RunWith 注释运行我的 JUnit 测试 Java 8 Gradle 4 2 1 我的 JUnit 类 public interface FastTest Category FastTest
  • 无法在Rails测试环境中使用TimescaleDB

    我被困在 Rails 中使用 TimescaleDB 开发中一切正常 但在我的测试套件中我无法插入任何数据 我尝试过的 A 使用 SQL 模式转储 这导致了我看到的原始错误消息 它确实为 TimescaleDB 创建了部分架构 但不是全部