partitioner_pg 0.1.0 → 0.2.0
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 +5 -5
- data/README.md +63 -20
- data/lib/partitioner_pg/separation_type/month.rb +78 -5
- data/lib/partitioner_pg/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e30a831e9e29196be95988158811a18398422ae7bd0ad6301906778f4f1fcd0a
|
4
|
+
data.tar.gz: 134c8445b3610c98365fca4b0a066ef668b368592b4094c53479acca5961ef33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7630fafde31ad687310dfce98bfa55719cf52038ec6a293be0bf484b875d0902f782d038ab188e8bfe823ac7f07f5d60295a476ad520d5d35e02ec71f5be2e6b
|
7
|
+
data.tar.gz: 2c940f85492295a3eb8cd23bc324c397991cd6bebacb0a360f7b07fcb3419bdd18defbf25f3f228e9a20c9ddf656b1d5ae3550b63d6222e3cf485d258bda7a71
|
data/README.md
CHANGED
@@ -1,36 +1,79 @@
|
|
1
|
-
#
|
1
|
+
# PartitionerPg
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
It's a gem for a partitioning Postgresql tables in Ruby on Rails.
|
4
|
+
Now gem can help you with partitioning tables by months. New table for each month.
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
9
8
|
Add this line to your application's Gemfile:
|
10
9
|
|
11
10
|
```ruby
|
12
|
-
gem '
|
11
|
+
gem 'partitioner_pg'
|
13
12
|
```
|
14
13
|
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install partitioner
|
22
|
-
|
23
14
|
## Usage
|
24
15
|
|
25
|
-
|
26
|
-
|
27
|
-
|
16
|
+
1) Include PartitionerPg into your model: `include PartitionerPg`. Also, you can specify parting column and some indexes.
|
17
|
+
Example:
|
18
|
+
```ruby
|
19
|
+
class YourModelName < ActiveRecord::Base
|
20
|
+
include PartitionerPg
|
21
|
+
|
22
|
+
# Point date or datetime column which will be used for monthly partitioning. Optional (:created_at uses by default)
|
23
|
+
def self.parting_column
|
24
|
+
:date
|
25
|
+
end
|
26
|
+
|
27
|
+
# List of indexes. Names of indexes will be generated by active migration. Optional.
|
28
|
+
def self.partition_table_indexes
|
29
|
+
[
|
30
|
+
%w[column1 column2]
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Map of indexes. Full name of named index will be generated as "index_[partition_name]_[name_of_index_from_map]". Optional.
|
35
|
+
def self.partition_table_named_indexes
|
36
|
+
{
|
37
|
+
:three_cols => %w[column1 column2 column3]
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
# List of unique indexes. Names of indexes wiil be generated by active migration. Optional.
|
42
|
+
def self.partition_table_unique_indexes
|
43
|
+
[
|
44
|
+
%w[column1 column2 column3 column4]
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Map of named unique indexes. Optional.
|
49
|
+
def self.partition_table_named_unique_indexes
|
50
|
+
{
|
51
|
+
:uniq => %w[column5 column6 column7]
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
```
|
56
|
+
2) Create migration and add some instructions to it. Generate migration:
|
28
57
|
|
29
|
-
|
58
|
+
```
|
59
|
+
rails g migration make_partitioning_of_you_table
|
60
|
+
```
|
30
61
|
|
31
|
-
|
62
|
+
add instructions to migration:
|
32
63
|
|
33
|
-
|
64
|
+
```ruby
|
65
|
+
class YouMigrationClassName
|
66
|
+
def change
|
67
|
+
YourModel.create_partitioning_by_month_trigger_sql
|
68
|
+
YourModel.create_month_table
|
69
|
+
YourModel.create_next_month_table
|
70
|
+
end
|
71
|
+
end
|
72
|
+
```
|
34
73
|
|
35
|
-
|
74
|
+
3) For correct work you need to create next partition every month.
|
75
|
+
We recommend you to create a rake task and run it once a month by crontab. Code for a rake task:
|
36
76
|
|
77
|
+
```ruby
|
78
|
+
YourModel.create_next_month_table
|
79
|
+
```
|
@@ -12,12 +12,18 @@ module PartitionerPg
|
|
12
12
|
def create_month_table(date=Date.today)
|
13
13
|
date_start = date.at_beginning_of_month
|
14
14
|
date_end = date.at_beginning_of_month.next_month
|
15
|
-
|
16
|
-
|
15
|
+
partition_table_name = name_of_partition_table(date)
|
16
|
+
sql = "CREATE TABLE IF NOT EXISTS #{partition_table_name} (
|
17
|
+
CHECK ( #{parting_column} >= DATE('#{date_start}') AND #{parting_column} < DATE('#{date_end}') )
|
17
18
|
) INHERITS (#{table_name});"
|
18
19
|
execute_sql(sql)
|
19
|
-
sql = "ALTER TABLE #{
|
20
|
+
sql = "ALTER TABLE #{partition_table_name} ADD PRIMARY KEY (id);"
|
20
21
|
execute_sql(sql)
|
22
|
+
|
23
|
+
create_partition_indexes(partition_table_name)
|
24
|
+
create_partition_named_indexes(partition_table_name)
|
25
|
+
create_partition_unique_indexes(partition_table_name)
|
26
|
+
create_partition_named_unique_indexes(partition_table_name)
|
21
27
|
end
|
22
28
|
|
23
29
|
def drop_month_table(date=Date.today)
|
@@ -33,8 +39,8 @@ module PartitionerPg
|
|
33
39
|
curM varchar(2);
|
34
40
|
tbl varchar(30);
|
35
41
|
BEGIN
|
36
|
-
select cast(DATE_PART('year', new
|
37
|
-
select lpad(cast(DATE_PART('month', new
|
42
|
+
select cast(DATE_PART('year', new.#{parting_column}) as varchar) into curY;
|
43
|
+
select lpad(cast(DATE_PART('month', new.#{parting_column}) as varchar), 2, '0') into curM;
|
38
44
|
tbl := '#{table_name}_y' || curY || 'm' || curM;
|
39
45
|
EXECUTE format('INSERT into %I values ($1.*);', tbl) USING NEW;
|
40
46
|
return NEW;
|
@@ -72,9 +78,76 @@ module PartitionerPg
|
|
72
78
|
DROP FUNCTION #{table_name}_delete_trigger();"
|
73
79
|
end
|
74
80
|
|
81
|
+
def create_partition_indexes(partition_table_name)
|
82
|
+
custom_indexes = partition_table_indexes.presence
|
83
|
+
return unless custom_indexes
|
84
|
+
|
85
|
+
custom_indexes.each { |custom_index| create_custom_index(partition_table_name, custom_index) }
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_partition_named_indexes(partition_table_name)
|
89
|
+
custom_indexes = partition_table_named_indexes.presence
|
90
|
+
return unless custom_indexes
|
91
|
+
|
92
|
+
custom_indexes.map{|name, custom_index|
|
93
|
+
index_name = "index_#{partition_table_name}_#{name}"
|
94
|
+
create_custom_named_index(partition_table_name, custom_index, index_name)
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def create_partition_unique_indexes(partition_table_name)
|
99
|
+
custom_unique_indexes = partition_table_unique_indexes.presence
|
100
|
+
return unless custom_unique_indexes
|
101
|
+
|
102
|
+
custom_unique_indexes.each { |custom_index| create_custom_index(partition_table_name, custom_index, true) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def create_partition_named_unique_indexes(partition_table_name)
|
106
|
+
custom_indexes = partition_table_named_unique_indexes.presence
|
107
|
+
return unless custom_indexes
|
108
|
+
|
109
|
+
custom_indexes.map{|name, custom_index|
|
110
|
+
index_name = "index_#{partition_table_name}_#{name}"
|
111
|
+
create_custom_named_index(partition_table_name, custom_index, index_name, true)
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
def create_custom_index(table_name, index_fields, is_unique = false)
|
116
|
+
ActiveRecord::Migration.add_index table_name, index_fields, unique: is_unique
|
117
|
+
end
|
118
|
+
|
119
|
+
def create_custom_named_index(table_name, index_fields, name, is_unique = false)
|
120
|
+
ActiveRecord::Migration.add_index table_name, index_fields, name: name, unique: is_unique
|
121
|
+
end
|
122
|
+
|
75
123
|
def name_of_partition_table(date=Date.today)
|
76
124
|
date.strftime("#{table_name}_y%Ym%m")
|
77
125
|
end
|
126
|
+
|
127
|
+
# Template method
|
128
|
+
# Column which will determine partition for row (must be date or datetime type). Default value is :created_at
|
129
|
+
def parting_column
|
130
|
+
:created_at
|
131
|
+
end
|
132
|
+
|
133
|
+
# Template method
|
134
|
+
def partition_table_indexes
|
135
|
+
#
|
136
|
+
end
|
137
|
+
|
138
|
+
def partition_table_named_indexes
|
139
|
+
#
|
140
|
+
end
|
141
|
+
|
142
|
+
# Template method
|
143
|
+
def partition_table_unique_indexes
|
144
|
+
#
|
145
|
+
end
|
146
|
+
|
147
|
+
# Template method
|
148
|
+
def partition_table_named_unique_indexes
|
149
|
+
#
|
150
|
+
end
|
78
151
|
end
|
79
152
|
end
|
80
153
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: partitioner_pg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aleksander Nikulin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
76
|
version: '0'
|
77
77
|
requirements: []
|
78
78
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.
|
79
|
+
rubygems_version: 2.7.3
|
80
80
|
signing_key:
|
81
81
|
specification_version: 4
|
82
82
|
summary: Gem for a partitoning PG tables
|