Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/crunchloop/timescaledb-rails
Ruby on Rails helpers for TimescaleDB
https://github.com/crunchloop/timescaledb-rails
rails ruby timescaledb
Last synced: 3 months ago
JSON representation
Ruby on Rails helpers for TimescaleDB
- Host: GitHub
- URL: https://github.com/crunchloop/timescaledb-rails
- Owner: crunchloop
- License: mit
- Created: 2022-01-28T18:06:29.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2024-02-10T19:18:28.000Z (about 1 year ago)
- Last Synced: 2024-09-14T13:41:06.007Z (5 months ago)
- Topics: rails, ruby, timescaledb
- Language: Ruby
- Homepage:
- Size: 159 KB
- Stars: 18
- Watchers: 5
- Forks: 1
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# TimescaleDB extension for Rails [![Gem Version](https://badge.fury.io/rb/timescaledb-rails.svg)](https://badge.fury.io/rb/timescaledb-rails) [![Actions Status](https://github.com/crunchloop/timescaledb-rails/workflows/CI/badge.svg?branch=main)](https://github.com/crunchloop/timescaledb-rails/actions?query=workflow%3ACI)
`timescaledb-rails` extends ActiveRecord PostgreSQL adapter and provides features from [TimescaleDB](https://www.timescale.com). It provides support for hypertables and other features added by TimescaleDB PostgreSQL extension.
## Installation
Install `timescaledb-rails` from RubyGems:
``` sh
$ gem install timescaledb-rails
```Or include it in your project's `Gemfile` with Bundler:
``` ruby
gem 'timescaledb-rails', '~> 0.1'
```## Usage
### Migrations
Create a hypertable from a PostgreSQL table
```ruby
class CreateEvent < ActiveRecord::Migration[7.0]
def change
create_table :events, id: false do |t|
t.string :name, null: false
t.time :occurred_at, null: falset.timestamps
endcreate_hypertable :events, :created_at, chunk_time_interval: '2 days'
end
end
```Create a hypertable without a PostgreSQL table
```ruby
class CreatePayloadHypertable < ActiveRecord::Migration[7.0]
def change
create_hypertable :payloads, :created_at, chunk_time_interval: '5 days' do |t|
t.string :ip, null: falset.timestamps
end
end
end
```Add hypertable compression policy
```ruby
class AddEventCompressionPolicy < ActiveRecord::Migration[7.0]
def up
enable_hypertable_compression :events, segment_by: :name, order_by: 'occurred_at DESC'add_hypertable_compression_policy :events, 20.days
enddef down
remove_hypertable_compression_policy :eventsdisable_hypertable_compression :events
end
end
```Add hypertable retention policy
```ruby
class AddEventRetentionPolicy < ActiveRecord::Migration[7.0]
def up
add_hypertable_retention_policy :events, 1.year
enddef down
remove_hypertable_retention_policy :events
end
end
```Add hypertable reorder policy
```ruby
class AddEventReorderPolicy < ActiveRecord::Migration[7.0]
def up
add_hypertable_reorder_policy :events, :index_events_on_created_at_and_name
enddef down
remove_hypertable_reorder_policy :events
end
end
```Create continuous aggregate
```ruby
class CreateTemperatureEventAggregate < ActiveRecord::Migration[7.0]
disable_ddl_transaction!def up
create_continuous_aggregate(
:temperature_events,
Event.time_bucket(1.day).avg(:value).temperature.to_sql
)add_continuous_aggregate_policy(:temperature_events, 1.month, 1.day, 1.hour)
enddef down
drop_continuous_aggregate(:temperature_events)remove_continuous_aggregate_policy(:temperature_events)
end
end
```> **Reversible Migrations:**
>
> Above examples implement `up`/`down` methods to better document all the different APIs. Feel free to use `change` method, timescaledb-rails defines all the reverse calls for each API method so Active Record can automatically figure out how to reverse your migration.### Models
If one of your models need TimescaleDB support, just include `Timescaledb::Rails::Model`
```ruby
class Payload < ActiveRecord::Base
include Timescaledb::Rails::Modelself.primary_key = 'id'
end
```When hypertable belongs to a non default schema, don't forget to override `table_name`
```ruby
class Event < ActiveRecord::Base
include Timescaledb::Rails::Modelself.table_name = 'tdb.events'
end
```Using `.find` is not recommended, to achieve more performant results, use these other find methods
```ruby
# When you know the exact time value
Payload.find_at_time(111, Time.new(2022, 01, 01, 10, 15, 30))# If you know that the record occurred after a given time
Payload.find_after(222, 11.days.ago)# Lastly, if you want to scope the search by a time range
Payload.find_between(333, 1.week.ago, 1.day.ago)
```If you need to query data for a specific time period, `Timescaledb::Rails::Model` includes useful scopes
```ruby
# If you want to get all records from last year
Event.last_year #=> [#, ...]# Or if you want to get records from this year
Event.this_year #=> [#, ...]# Or even getting records from today
Event.today #=> [#, ...]
```Here the list of all available scopes
* last_year
* last_month
* last_week
* this_year
* this_month
* this_week
* yesterday
* todayIf you still need to query data by other time periods, take a look at these other scopes
```ruby
# If you want to get all records that occurred in the last 30 minutes
Event.after(30.minutes.ago) #=> [#, ...]# If you want to get records that occurred in the last 4 days, excluding today
Event.between(4.days.ago, 1.day.ago) #=> [#, ...]# If you want to get records that occurred at a specific time
Event.at_time(Time.new(2023, 01, 04, 10, 20, 30)) #=> [#, ...]
```If you need information about your hypertable, use the following helper methods to get useful information
```ruby
# Hypertable metadata
Event.hypertable #=> ## Hypertable chunks metadata
Event.hypertable_chunks #=> [#, ...]# Hypertable jobs, it includes jobs like compression, retention or reorder policies, etc.
Event.hypertable_jobs #=> [#, ...]# Hypertable dimensions, like time or space dimensions
Event.hypertable_dimensions #=> [#, ...]# Hypertable compression settings
Event.hypertable_compression_settings #=> [#, ...]
```If you need to compress or decompress a specific chunk
```ruby
chunk = Event.hypertable_chunks.firstchunk.compress! unless chunk.is_compressed?
chunk.decompress! if chunk.is_compressed?
```If you need to reorder a specific chunk
```ruby
chunk = Event.hypertable_chunks.first# If an index is not specified, it will use the one from the reorder policy
# In case there is no reorder policy index it will raise an ArgumentError
chunk.reorder!# If an index is specified it will use that index
chunk.reorder!(index)
```If you need to manually refresh a continuous aggregate
```ruby
aggregate = Event.hypertable.continuous_aggregates.firstaggregate.refresh!(5.days.ago, 1.day.ago)
```### Hyperfunctions
#### Time bucket
You can call the time bucket function with an interval (note that leaving the target column blank will use the default time column of the hypertable)
```ruby
Event.time_bucket(1.day)Event.time_bucket('1 day')
Event.time_bucket(1.day, :created_at)
Event.time_bucket(1.day, 'occurred_at')
```You may add aggregation like so:
```ruby
Event.time_bucket(1.day).avg(:column)
Event.time_bucket(1.day).sum(:column)
Event.time_bucket(1.day).min(:column)
Event.time_bucket(1.day).max(:column)
Event.time_bucket(1.day).count
```## Contributing
Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests.
## Supported Ruby/Rails versions
Supported Ruby/Rails versions are listed in [`.github/workflows/ci.yaml`](./.github/workflows/ci.yaml)
## License
Released under the MIT License. See the [LICENSE][] file for further details.
[license]: LICENSE
## About Crunchloop
![crunchloop](https://s3.amazonaws.com/crunchloop.io/logo-blue.png)
`timescaledb-rails` is supported with :heart: by [Crunchloop](https://crunchloop.io). We strongly believe in giving back :rocket:. Let's work together [`Get in touch`](https://crunchloop.io/#contact).