timescaledb 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +41 -9
- data/bin/console +1 -1
- data/bin/tsdb +2 -2
- data/docs/command_line.md +178 -0
- data/docs/img/lttb_example.png +0 -0
- data/docs/img/lttb_sql_vs_ruby.gif +0 -0
- data/docs/img/lttb_zoom.gif +0 -0
- data/docs/index.md +61 -0
- data/docs/migrations.md +69 -0
- data/docs/models.md +78 -0
- data/docs/toolkit.md +394 -0
- data/docs/toolkit_lttb_tutorial.md +557 -0
- data/docs/toolkit_lttb_zoom.md +357 -0
- data/docs/videos.md +16 -0
- data/examples/all_in_one/all_in_one.rb +39 -5
- data/examples/all_in_one/benchmark_comparison.rb +108 -0
- data/examples/all_in_one/caggs.rb +93 -0
- data/examples/all_in_one/query_data.rb +78 -0
- data/examples/toolkit-demo/compare_volatility.rb +64 -0
- data/examples/toolkit-demo/lttb/README.md +15 -0
- data/examples/toolkit-demo/lttb/lttb.rb +92 -0
- data/examples/toolkit-demo/lttb/lttb_sinatra.rb +139 -0
- data/examples/toolkit-demo/lttb/lttb_test.rb +21 -0
- data/examples/toolkit-demo/lttb/views/index.erb +27 -0
- data/examples/toolkit-demo/lttb-zoom/README.md +13 -0
- data/examples/toolkit-demo/lttb-zoom/lttb_zoomable.rb +90 -0
- data/examples/toolkit-demo/lttb-zoom/views/index.erb +33 -0
- data/lib/timescaledb/acts_as_time_vector.rb +18 -0
- data/lib/timescaledb/dimensions.rb +1 -0
- data/lib/timescaledb/hypertable.rb +5 -1
- data/lib/timescaledb/migration_helpers.rb +11 -0
- data/lib/timescaledb/stats_report.rb +1 -1
- data/lib/timescaledb/toolkit/helpers.rb +20 -0
- data/lib/timescaledb/toolkit/time_vector.rb +66 -0
- data/lib/timescaledb/toolkit.rb +3 -0
- data/lib/timescaledb/version.rb +1 -1
- data/lib/timescaledb.rb +1 -0
- data/mkdocs.yml +33 -0
- metadata +30 -4
- data/examples/all_in_one/Gemfile +0 -11
- data/examples/all_in_one/Gemfile.lock +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b622fffc9a920a95e1c0615df32fa13e6b60d21198ebd39a6c46d27a66e11df4
|
4
|
+
data.tar.gz: 9da077e24cb64120e1d235e05234299f9c2fb7cbbbd63e50a68a13bad3a23898
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4c098c20e3a99f5c8798f5ed2e29c095b5982b55defc5612128a33bf840c01d7eb457df2a5cd83fc41243be9b48184a8bc9b585800d2d7daa28085793263246
|
7
|
+
data.tar.gz: b1420ac494f3a1ed6ebbd4ebd3701a9a3d33b122bbf3d6dd4b15c94159ce5299d24d0f08c68ef612b6758859b388811415593d4512fc39bfbff26876ec82efea
|
data/README.md
CHANGED
@@ -29,7 +29,7 @@ tsdb postgres://<user>@localhost:5432/<dbname> --stats
|
|
29
29
|
Or just check the stats:
|
30
30
|
|
31
31
|
```bash
|
32
|
-
tsdb "postgres
|
32
|
+
tsdb "postgres://<user>@localhost:5432/timescaledb_test" --stats
|
33
33
|
```
|
34
34
|
|
35
35
|
These is a sample output from database example with almost no data:
|
@@ -53,13 +53,13 @@ as the example of database.
|
|
53
53
|
|
54
54
|
|
55
55
|
```bash
|
56
|
-
psql postgres
|
56
|
+
psql postgres://<user>@localhost:5432/playground -f caggs.sql
|
57
57
|
```
|
58
58
|
|
59
59
|
Then use `tsdb` in the command line with the same URI and `--stats`:
|
60
60
|
|
61
61
|
```bash
|
62
|
-
tsdb postgres
|
62
|
+
tsdb postgres://<user>@localhost:5432/playground --stats
|
63
63
|
{:hypertables=>
|
64
64
|
{:count=>1,
|
65
65
|
:uncompressed=>1,
|
@@ -80,7 +80,7 @@ the context has a hypertable named `ticks` and a view named `ohlc_1m`.
|
|
80
80
|
|
81
81
|
|
82
82
|
```ruby
|
83
|
-
tsdb postgres
|
83
|
+
tsdb postgres://<user>@localhost:5432/playground --console
|
84
84
|
pry(Timescale)>
|
85
85
|
```
|
86
86
|
|
@@ -223,6 +223,19 @@ You can check the [all_in_one.rb](examples/all_in_one/all_in_one.rb) example tha
|
|
223
223
|
6. Check chunk status
|
224
224
|
7. Decompress a chunk
|
225
225
|
|
226
|
+
### Toolkit
|
227
|
+
|
228
|
+
Toolkit contains a lot of extra features to analyse data more deeply directly in
|
229
|
+
the SQL. There are a few examples in the [examples/toolkit-demo](examples/toolkit-demo)
|
230
|
+
folder that can let you benchmark and see the differences between implementing
|
231
|
+
the algorithm directly in Ruby or directly in SQL using the [Timescaledb
|
232
|
+
Toolkit](https://github.com/timescale/timescaledb-toolkit) extension.
|
233
|
+
|
234
|
+
For now you can benchmark and compare:
|
235
|
+
|
236
|
+
1. [volatility](examples/toolkit-demo/compare_volatility.rb) algorithm.
|
237
|
+
2. [lttb](examples/toolkit-demo/lttb/lttb_sinatra.rb) algorithm.
|
238
|
+
|
226
239
|
### Testing
|
227
240
|
|
228
241
|
If you need some inspiration for how are you going to test your hypertables,
|
@@ -360,7 +373,17 @@ To get compression settings for all hypertables: `Timescaledb.compression_settin
|
|
360
373
|
|
361
374
|
### Scopes
|
362
375
|
|
363
|
-
|
376
|
+
The `acts_as_hypertable` macro can be very useful to generate some extra scopes
|
377
|
+
for you. Example of a weather condition:
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
class Condition < ActiveRecord::Base
|
381
|
+
acts_as_hypertable time_column: "time"
|
382
|
+
end
|
383
|
+
```
|
384
|
+
|
385
|
+
Through the [ActsAsHypertable](./lib/timescaledb/acts_as_hypertable) on the model,
|
386
|
+
a few scopes are created based on the `time_column` argument:
|
364
387
|
|
365
388
|
| Scope name | What they return |
|
366
389
|
|------------------------|---------------------------------------|
|
@@ -374,6 +397,16 @@ When you enable ActsAsHypertable on your model, we include a couple default scop
|
|
374
397
|
|
375
398
|
All time-related scopes respect your application's timezone.
|
376
399
|
|
400
|
+
When you enable ActsAsTimeVector on your model, we include a couple default scopes. They are:
|
401
|
+
|
402
|
+
```ruby
|
403
|
+
class Condition < ActiveRecord::Base
|
404
|
+
acts_as_time_vector time_column: "time",
|
405
|
+
value_column: "temperature",
|
406
|
+
segment_by: "device_id"
|
407
|
+
end
|
408
|
+
```
|
409
|
+
|
377
410
|
## RSpec Hooks
|
378
411
|
|
379
412
|
In case you want to use TimescaleDB on a Rails environment, you may have some
|
@@ -422,7 +455,7 @@ You can put some postgres URI directly as a parameter of
|
|
422
455
|
`tsdb`. Here is an example from the console:
|
423
456
|
|
424
457
|
```bash
|
425
|
-
tsdb "postgres
|
458
|
+
tsdb "postgres://<user>@localhost:5432/timescaledb_test"
|
426
459
|
```
|
427
460
|
|
428
461
|
## More resources
|
@@ -442,12 +475,11 @@ You can watch all episodes here:
|
|
442
475
|
|
443
476
|
Here is a list of functions that would be great to have:
|
444
477
|
|
445
|
-
- [ ] Dump and Restore Timescale metadata - Like db/schema.rb but for Timescale configuration.
|
446
478
|
- [ ] Add data nodes support
|
447
479
|
|
448
480
|
## Contributing
|
449
481
|
|
450
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/jonatas/
|
482
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jonatas/timescaledb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/jonatas/timescaledb/blob/master/CODE_OF_CONDUCT.md).
|
451
483
|
|
452
484
|
## License
|
453
485
|
|
@@ -455,4 +487,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
455
487
|
|
456
488
|
## Code of Conduct
|
457
489
|
|
458
|
-
Everyone interacting in the Timescale project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jonatas/
|
490
|
+
Everyone interacting in the Timescale project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jonatas/timescaledb/blob/master/CODE_OF_CONDUCT.md).
|
data/bin/console
CHANGED
data/bin/tsdb
CHANGED
@@ -9,7 +9,7 @@ Timescaledb::Hypertable.find_each do |hypertable|
|
|
9
9
|
class_name = hypertable.hypertable_name.singularize.camelize
|
10
10
|
model = Class.new(ActiveRecord::Base) do
|
11
11
|
self.table_name = hypertable.hypertable_name
|
12
|
-
acts_as_hypertable
|
12
|
+
acts_as_hypertable time_column: hypertable.main_dimension.column_name
|
13
13
|
end
|
14
14
|
Timescaledb.const_set(class_name, model)
|
15
15
|
end
|
@@ -44,5 +44,5 @@ if ARGV.index("--stats")
|
|
44
44
|
end
|
45
45
|
|
46
46
|
if ARGV.index("--console")
|
47
|
-
Pry.start(
|
47
|
+
Pry.start(Timescaledb)
|
48
48
|
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
# Command line application
|
2
|
+
|
3
|
+
When you install the gem locally, a new command line application named `tsdb` will be available on your command line.
|
4
|
+
|
5
|
+
## The `tsdb` CLI
|
6
|
+
|
7
|
+
It accepts a Postgresql URI and some extra flags that can help you to get more info from your TimescaleDB server:
|
8
|
+
|
9
|
+
```bash
|
10
|
+
tsdb <uri> --stats
|
11
|
+
```
|
12
|
+
|
13
|
+
Where the `<uri>` is replaced with params from your connection like:
|
14
|
+
|
15
|
+
```bash
|
16
|
+
tsdb postgres://<user>@localhost:5432/<dbname> --stats
|
17
|
+
```
|
18
|
+
|
19
|
+
Or merely check the stats:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
tsdb "postgres://<user>@localhost:5432/timescaledb_test" --stats
|
23
|
+
```
|
24
|
+
|
25
|
+
Here is a sample output from a database example with almost no data:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
{:hypertables=>
|
29
|
+
{:count=>3,
|
30
|
+
:uncompressed=>2,
|
31
|
+
:chunks=>{:total=>1, :compressed=>0, :uncompressed=>1},
|
32
|
+
:size=>{:befoe_compressing=>"80 KB", :after_compressing=>"0 Bytes"}},
|
33
|
+
:continuous_aggregates=>{:count=>1},
|
34
|
+
:jobs_stats=>[{:success=>nil, :runs=>nil, :failures=>nil}]}
|
35
|
+
```
|
36
|
+
|
37
|
+
To start a interactive ruby/[pry](https://github.com/pry/pry) console use `--console`:
|
38
|
+
The console will dynamically create models for all hypertables that it finds
|
39
|
+
in the database.
|
40
|
+
|
41
|
+
Let's consider the [caggs.sql](https://gist.github.com/jonatas/95573ad8744994094ec9f284150004f9#file-caggs-sql) as the example of a database.
|
42
|
+
|
43
|
+
|
44
|
+
```bash
|
45
|
+
psql postgres://<user>@localhost:5432/playground -f caggs.sql
|
46
|
+
```
|
47
|
+
|
48
|
+
Then use `tsdb` in the command line with the same URI and `--stats`:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
tsdb postgres://<user>@localhost:5432/playground --stats
|
52
|
+
{:hypertables=>
|
53
|
+
{:count=>1,
|
54
|
+
:uncompressed=>1,
|
55
|
+
:approximate_row_count=>{"ticks"=>352},
|
56
|
+
:chunks=>{:total=>1, :compressed=>0, :uncompressed=>1},
|
57
|
+
:size=>{:uncompressed=>"88 KB", :compressed=>"0 Bytes"}},
|
58
|
+
:continuous_aggregates=>{:total=>1},
|
59
|
+
:jobs_stats=>[{:success=>nil, :runs=>nil, :failures=>nil}]}
|
60
|
+
```
|
61
|
+
|
62
|
+
To have some interactive playground with the actual database using ruby, just
|
63
|
+
try the same command before changing from `--stats` to `--console`:
|
64
|
+
|
65
|
+
### tsdb --console
|
66
|
+
|
67
|
+
We are using the same database from the previous example for this context which contains a hypertable named `ticks` and a view called `ohlc_1m`.
|
68
|
+
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
tsdb postgres://<user>@localhost:5432/playground --console
|
72
|
+
pry(Timescale)>
|
73
|
+
```
|
74
|
+
|
75
|
+
The `tsdb` CLI will automatically create ActiveRecord models for hypertables and the continuous aggregates views.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
Tick
|
79
|
+
=> Timescaledb::Tick(time: datetime, symbol: string, price: decimal, volume: integer)
|
80
|
+
```
|
81
|
+
|
82
|
+
Note that it's only created for this session and will never cache in the
|
83
|
+
library or any other place.
|
84
|
+
|
85
|
+
In this case, the `Tick` model comes from the `ticks` hypertable found in the database.
|
86
|
+
It contains several methods inherited from the `acts_as_hypertable` macro.
|
87
|
+
|
88
|
+
Let's start with the `.hypertable` method.
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Tick.hypertable
|
92
|
+
=> #<Timescaledb::Hypertable:0x00007fe99c258900
|
93
|
+
hypertable_schema: "public",
|
94
|
+
hypertable_name: "ticks",
|
95
|
+
owner: "jonatasdp",
|
96
|
+
num_dimensions: 1,
|
97
|
+
num_chunks: 1,
|
98
|
+
compression_enabled: false,
|
99
|
+
is_distributed: false,
|
100
|
+
replication_factor: nil,
|
101
|
+
data_nodes: nil,
|
102
|
+
tablespaces: nil>
|
103
|
+
```
|
104
|
+
|
105
|
+
The core of the hypertables is the fragmentation of the data into chunks, the child tables that distribute the data. You can check all chunks directly from the hypertable relation.
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
Tick.hypertable.chunks
|
109
|
+
unknown OID 2206: failed to recognize type of 'primary_dimension_type'. It will cast as a String.
|
110
|
+
=> [#<Timescaledb::Chunk:0x00007fe99c31b068
|
111
|
+
hypertable_schema: "public",
|
112
|
+
hypertable_name: "ticks",
|
113
|
+
chunk_schema: "_timescaledb_internal",
|
114
|
+
chunk_name: "_hyper_33_17_chunk",
|
115
|
+
primary_dimension: "time",
|
116
|
+
primary_dimension_type: "timestamp without time zone",
|
117
|
+
range_start: 1999-12-30 00:00:00 +0000,
|
118
|
+
range_end: 2000-01-06 00:00:00 +0000,
|
119
|
+
range_start_integer: nil,
|
120
|
+
range_end_integer: nil,
|
121
|
+
is_compressed: false,
|
122
|
+
chunk_tablespace: nil,
|
123
|
+
data_nodes: nil>]
|
124
|
+
```
|
125
|
+
|
126
|
+
> Chunks are created by partitioning the hypertable data into one
|
127
|
+
> (or potentially multiple) dimensions. All hypertables are partitions by the
|
128
|
+
> values belonging to a time column, which may be in timestamp, date, or
|
129
|
+
> various integer forms. If the time partitioning interval is one day,
|
130
|
+
> for example, then rows with timestamps that belong to the same day are co-located
|
131
|
+
> within the same chunk, while rows belonging to different days belong to different chunks.
|
132
|
+
> Learn more [here](https://docs.timescale.com/timescaledb/latest/overview/core-concepts/hypertables-and-chunks/).
|
133
|
+
|
134
|
+
Another core concept of TimescaleDB is compression. With data partitioned, it
|
135
|
+
becomes very convenient to compress and decompress chunks independently.
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
Tick.hypertable.chunks.first.compress!
|
139
|
+
ActiveRecord::StatementInvalid: PG::FeatureNotSupported: ERROR: compression not enabled on "ticks"
|
140
|
+
DETAIL: It is not possible to compress chunks on a hypertable that does not have compression enabled.
|
141
|
+
HINT: Enable compression using ALTER TABLE with the timescaledb.compress option.
|
142
|
+
```
|
143
|
+
|
144
|
+
As compression is not enabled, let's do it by executing plain SQL directly from the actual context. To borrow a connection, let's use the Tick object.
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
Tick.connection.execute("ALTER TABLE ticks SET (timescaledb.compress)") # => PG_OK
|
148
|
+
```
|
149
|
+
|
150
|
+
And now, it's possible to compress and decompress:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
Tick.hypertable.chunks.first.compress!
|
154
|
+
Tick.hypertable.chunks.first.decompress!
|
155
|
+
```
|
156
|
+
Learn more about TimescaleDB compression [here](https://docs.timescale.com/timescaledb/latest/overview/core-concepts/compression/).
|
157
|
+
|
158
|
+
The `ohlc_1m` view is also available as an ActiveRecord:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
Ohlc1m
|
162
|
+
=> Timescaledb::Ohlc1m(bucket: datetime, symbol: string, open: decimal, high: decimal, low: decimal, close: decimal, volume: integer)
|
163
|
+
```
|
164
|
+
|
165
|
+
And you can run any query as you do with regular active record queries.
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
Ohlc1m.order(bucket: :desc).last
|
169
|
+
=> #<Timescaledb::Ohlc1m:0x00007fe99c2c38e0
|
170
|
+
bucket: 2000-01-01 00:00:00 UTC,
|
171
|
+
symbol: "SYMBOL",
|
172
|
+
open: 0.13e2,
|
173
|
+
high: 0.3e2,
|
174
|
+
low: 0.1e1,
|
175
|
+
close: 0.1e2,
|
176
|
+
volume: 27600>
|
177
|
+
```
|
178
|
+
|
Binary file
|
Binary file
|
Binary file
|
data/docs/index.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# The TimescaleDB Ruby Gem
|
2
|
+
|
3
|
+
Welcome to the TimescaleDB gem! To experiment with the code, start installing the
|
4
|
+
gem:
|
5
|
+
|
6
|
+
## Installing
|
7
|
+
|
8
|
+
You can install the gem locally:
|
9
|
+
|
10
|
+
```bash
|
11
|
+
gem install timescaledb
|
12
|
+
```
|
13
|
+
|
14
|
+
Or require it directly in the Gemfile of your project:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem "timescaledb"
|
18
|
+
```
|
19
|
+
|
20
|
+
## Features
|
21
|
+
|
22
|
+
* The model can use the [acts_as_hypertable](https://github.com/jonatas/timescaledb/tree/master/lib/timescaledb/acts_as_hypertable.rb) macro. Check more on [models](models) documentation.
|
23
|
+
* The ActiveRecord [migrations](migrations) can use the [create_table](https://github.com/jonatas/timescaledb/tree/master/lib/timescaledb/migration_helpers.rb) supporting the `hypertable` keyword. It's also enabling you to add retention and continuous aggregates policies
|
24
|
+
* A standalone `create_hypertable` macro is also allowed in the migrations.
|
25
|
+
* Testing also becomes easier as the [schema dumper](https://github.com/jonatas/timescaledb/tree/master/lib/timescaledb/schema_dumper.rb) will automatically introduce the hypertables to all environments.
|
26
|
+
* It also contains a [scenic extension](https://github.com/jonatas/timescaledb/tree/master/lib/timescaledb/scenic/extension.rb) to work with [scenic views](https://github.com/scenic-views/scenic) as it's a wide adoption in the community.
|
27
|
+
* The gem is also packed with a [command line utility](command_line) that makes it easier to navigate in your database with Pry and all your hypertables available in a Ruby style.
|
28
|
+
|
29
|
+
## Examples
|
30
|
+
|
31
|
+
The [all_in_one](https://github.com/jonatas/timescaledb/tree/master/examples/all_in_one/all_in_one.rb) example shows:
|
32
|
+
|
33
|
+
1. Create a hypertable with compression settings
|
34
|
+
2. Insert data
|
35
|
+
3. Run some queries
|
36
|
+
4. Check chunk size per model
|
37
|
+
5. Compress a chunk
|
38
|
+
6. Check chunk status
|
39
|
+
7. Decompress a chunk
|
40
|
+
|
41
|
+
The [ranking](https://github.com/jonatas/timescaledb/tree/master/examples/ranking) example shows how to configure a Rails app and navigate all the features available.
|
42
|
+
|
43
|
+
## Extra resources
|
44
|
+
|
45
|
+
If you need extra help, please join the fantastic [timescale community](https://www.timescale.com/community)
|
46
|
+
or ask your question on [StackOverflow](https://stackoverflow.com/questions/tagged/timescaledb) using the `#timescaledb` tag.
|
47
|
+
|
48
|
+
If you want to go deeper in the library, the [videos](videos) links to all
|
49
|
+
live-coding sessions showed how [@jonatasdp](https://twitter.com/jonatasdp) built the gem.
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jonatas/timescaledb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/jonatas/timescaledb/blob/master/CODE_OF_CONDUCT.md).
|
54
|
+
|
55
|
+
## License
|
56
|
+
|
57
|
+
The gem is available as open source under the [MIT License](https://opensource.org/licenses/MIT).
|
58
|
+
|
59
|
+
## Code of Conduct
|
60
|
+
|
61
|
+
Everyone interacting in the Timescale project's codebases, issue trackers, chat rooms, and mailing lists is expected to follow the [code of conduct](https://github.com/jonatas/timescaledb/blob/master/CODE_OF_CONDUCT.md).
|
data/docs/migrations.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# ActiveRecord migrations helpers for Timescale
|
2
|
+
|
3
|
+
Create table is now with the `hypertable` keyword allowing to pass a few options
|
4
|
+
to the function call while also using the `create_table` method:
|
5
|
+
|
6
|
+
## create_table with the `:hypertable` option
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
hypertable_options = {
|
10
|
+
time_column: 'created_at',
|
11
|
+
chunk_time_interval: '1 min',
|
12
|
+
compress_segmentby: 'identifier',
|
13
|
+
compression_interval: '7 days'
|
14
|
+
}
|
15
|
+
|
16
|
+
create_table(:events, id: false, hypertable: hypertable_options) do |t|
|
17
|
+
t.string :identifier, null: false
|
18
|
+
t.jsonb :payload
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
## The `create_continuous_aggregate` helper
|
24
|
+
|
25
|
+
This example shows a ticks table grouping ticks as OHLCV histograms for every
|
26
|
+
minute.
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
hypertable_options = {
|
30
|
+
time_column: 'created_at',
|
31
|
+
chunk_time_interval: '1 min',
|
32
|
+
compress_segmentby: 'symbol',
|
33
|
+
compress_orderby: 'created_at',
|
34
|
+
compression_interval: '7 days'
|
35
|
+
}
|
36
|
+
create_table :ticks, hypertable: hypertable_options, id: false do |t|
|
37
|
+
t.string :symbol
|
38
|
+
t.decimal :price
|
39
|
+
t.integer :volume
|
40
|
+
t.timestamps
|
41
|
+
end
|
42
|
+
Tick = Class.new(ActiveRecord::Base) do
|
43
|
+
self.table_name = 'ticks'
|
44
|
+
self.primary_key = 'symbol'
|
45
|
+
acts_as_hypertable
|
46
|
+
end
|
47
|
+
|
48
|
+
query = Tick.select(<<~QUERY)
|
49
|
+
time_bucket('1m', created_at) as time,
|
50
|
+
symbol,
|
51
|
+
FIRST(price, created_at) as open,
|
52
|
+
MAX(price) as high,
|
53
|
+
MIN(price) as low,
|
54
|
+
LAST(price, created_at) as close,
|
55
|
+
SUM(volume) as volume").group("1,2")
|
56
|
+
QUERY
|
57
|
+
|
58
|
+
options = {
|
59
|
+
with_data: false,
|
60
|
+
refresh_policies: {
|
61
|
+
start_offset: "INTERVAL '1 month'",
|
62
|
+
end_offset: "INTERVAL '1 minute'",
|
63
|
+
schedule_interval: "INTERVAL '1 minute'"
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
create_continuous_aggregate('ohlc_1m', query, **options)
|
68
|
+
```
|
69
|
+
|
data/docs/models.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Models
|
2
|
+
|
3
|
+
The ActiveRecord is the default ORM in the Ruby community. We have introduced a macro that helps you to inject the behavior as other libraries do in the Rails ecosystem.
|
4
|
+
|
5
|
+
## The `acts_as_hypertable` macro
|
6
|
+
|
7
|
+
You can declare a Rails model as a Hypertable by invoking the `acts_as_hypertable` macro. This macro extends your existing model with timescaledb-related functionality.
|
8
|
+
model:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
class Event < ActiveRecord::Base
|
12
|
+
acts_as_hypertable
|
13
|
+
end
|
14
|
+
```
|
15
|
+
|
16
|
+
By default, ActsAsHypertable assumes a record's _time_column_ is called `created_at`.
|
17
|
+
|
18
|
+
### Options
|
19
|
+
|
20
|
+
If you are using a different time_column name, you can specify it as follows when invoking the `acts_as_hypertable` macro:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
class Event < ActiveRecord::Base
|
24
|
+
acts_as_hypertable time_column :timestamp
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
### Chunks
|
29
|
+
|
30
|
+
To get all the chunks from a model's hypertable, you can use `.chunks`.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
Event.chunks # => [#<Timescaledb::Chunk>, ...]
|
34
|
+
```
|
35
|
+
|
36
|
+
### Hypertable metadata
|
37
|
+
|
38
|
+
To get the models' hypertable metadata, you can use `.hypertable`.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
Event.hypertable # => #<Timescaledb::Hypertable>
|
42
|
+
```
|
43
|
+
|
44
|
+
To get hypertable metadata for all hypertables: `Timescaledb.hypertables`.
|
45
|
+
|
46
|
+
### Compression Settings
|
47
|
+
|
48
|
+
Compression settings are accessible through the hypertable.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
Event.hypertable.compression_settings # => [#<Timescaledb::CompressionSettings>, ...]
|
52
|
+
```
|
53
|
+
|
54
|
+
To get compression settings for all hypertables: `Timescaledb.compression_settings`.
|
55
|
+
|
56
|
+
### Scopes
|
57
|
+
|
58
|
+
When you enable ActsAsHypertable on your model, we include a few default scopes. They are:
|
59
|
+
|
60
|
+
| Scope name | What they return |
|
61
|
+
|------------------------|---------------------------------------|
|
62
|
+
| `Model.previous_month` | Records created in the previous month |
|
63
|
+
| `Model.previous_week` | Records created in the previous week |
|
64
|
+
| `Model.this_month` | Records created this month |
|
65
|
+
| `Model.this_week` | Records created this week |
|
66
|
+
| `Model.yesterday` | Records created yesterday |
|
67
|
+
| `Model.today` | Records created today |
|
68
|
+
| `Model.last_hour` | Records created in the last hour |
|
69
|
+
|
70
|
+
All time-related scopes respect your application's timezone.
|
71
|
+
|
72
|
+
|
73
|
+
## Scenic integration
|
74
|
+
|
75
|
+
The [Scenic](https://github.com/scenic-views/scenic) gem is easy to
|
76
|
+
manage database view definitions for a Rails application. Unfortunately, TimescaleDB's continuous aggregates are more complex than regular PostgreSQL views, and the schema dumper included with Scenic can't dump a complete definition.
|
77
|
+
|
78
|
+
This gem automatically configures Scenic to use a `Timescaledb::Scenic::Adapter.` which will correctly handle schema dumping.
|