pgslice 0.7.1 → 0.7.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/CHANGELOG.md +4 -0
- data/README.md +16 -16
- data/lib/pgslice/cli/add_partitions.rb +5 -1
- data/lib/pgslice/cli/fill.rb +1 -1
- data/lib/pgslice/cli/prep.rb +2 -2
- data/lib/pgslice/cli/swap.rb +1 -1
- data/lib/pgslice/helpers.rb +18 -5
- data/lib/pgslice/table.rb +13 -12
- data/lib/pgslice/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 80b19b5f7b8bc83c0e75061952d6b26b1dc6ddba6eec34c1ca6a25ec53050201
|
|
4
|
+
data.tar.gz: b59c9d219b0bc539b5e45c078ff7bdd9bf3df9a3856574f811a19a33052c58bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: db38bae9e3a120383329c1a9dbb2dc031700774bc57b0e5153a49c5f1683018d3752d363ea35976ca09f3da36ffa249f2bd9cdef74797461af60302089facef9
|
|
7
|
+
data.tar.gz: f4d51f9a864901a7305224b720c3e261a95a35584dc42d2559ca15068d5c2bea87755c4321c57aa76d60413c742b3cf5b767b731e759c83b2ce8c69502ecd4a0
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -110,17 +110,17 @@ pgslice add_partitions visits --intermediate --past 1 --future 1
|
|
|
110
110
|
```sql
|
|
111
111
|
BEGIN;
|
|
112
112
|
|
|
113
|
-
CREATE TABLE "public"."
|
|
113
|
+
CREATE TABLE "public"."visits_202508" PARTITION OF "public"."visits_intermediate" FOR VALUES FROM ('2025-08-01') TO ('2025-09-01');
|
|
114
114
|
|
|
115
|
-
ALTER TABLE "public"."
|
|
115
|
+
ALTER TABLE "public"."visits_202508" ADD PRIMARY KEY ("id");
|
|
116
116
|
|
|
117
|
-
CREATE TABLE "public"."
|
|
117
|
+
CREATE TABLE "public"."visits_202509" PARTITION OF "public"."visits_intermediate" FOR VALUES FROM ('2025-09-01') TO ('2025-10-01');
|
|
118
118
|
|
|
119
|
-
ALTER TABLE "public"."
|
|
119
|
+
ALTER TABLE "public"."visits_202509" ADD PRIMARY KEY ("id");
|
|
120
120
|
|
|
121
|
-
CREATE TABLE "public"."
|
|
121
|
+
CREATE TABLE "public"."visits_202510" PARTITION OF "public"."visits_intermediate" FOR VALUES FROM ('2025-10-01') TO ('2025-11-01');
|
|
122
122
|
|
|
123
|
-
ALTER TABLE "public"."
|
|
123
|
+
ALTER TABLE "public"."visits_202510" ADD PRIMARY KEY ("id");
|
|
124
124
|
|
|
125
125
|
COMMIT;
|
|
126
126
|
```
|
|
@@ -133,17 +133,17 @@ pgslice fill visits
|
|
|
133
133
|
/* 1 of 3 */
|
|
134
134
|
INSERT INTO "public"."visits_intermediate" ("id", "user_id", "ip", "created_at")
|
|
135
135
|
SELECT "id", "user_id", "ip", "created_at" FROM "public"."visits"
|
|
136
|
-
WHERE "id" > 0 AND "id" <= 10000 AND "created_at" >= '
|
|
136
|
+
WHERE "id" > 0 AND "id" <= 10000 AND "created_at" >= '2025-08-01'::date AND "created_at" < '2025-11-01'::date
|
|
137
137
|
|
|
138
138
|
/* 2 of 3 */
|
|
139
139
|
INSERT INTO "public"."visits_intermediate" ("id", "user_id", "ip", "created_at")
|
|
140
140
|
SELECT "id", "user_id", "ip", "created_at" FROM "public"."visits"
|
|
141
|
-
WHERE "id" > 10000 AND "id" <= 20000 AND "created_at" >= '
|
|
141
|
+
WHERE "id" > 10000 AND "id" <= 20000 AND "created_at" >= '2025-08-01'::date AND "created_at" < '2025-11-01'::date
|
|
142
142
|
|
|
143
143
|
/* 3 of 3 */
|
|
144
144
|
INSERT INTO "public"."visits_intermediate" ("id", "user_id", "ip", "created_at")
|
|
145
145
|
SELECT "id", "user_id", "ip", "created_at" FROM "public"."visits"
|
|
146
|
-
WHERE "id" > 20000 AND "id" <= 30000 AND "created_at" >= '
|
|
146
|
+
WHERE "id" > 20000 AND "id" <= 30000 AND "created_at" >= '2025-08-01'::date AND "created_at" < '2025-11-01'::date
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
```sh
|
|
@@ -151,11 +151,11 @@ pgslice analyze visits
|
|
|
151
151
|
```
|
|
152
152
|
|
|
153
153
|
```sql
|
|
154
|
-
ANALYZE VERBOSE "public"."
|
|
154
|
+
ANALYZE VERBOSE "public"."visits_202508";
|
|
155
155
|
|
|
156
|
-
ANALYZE VERBOSE "public"."
|
|
156
|
+
ANALYZE VERBOSE "public"."visits_202509";
|
|
157
157
|
|
|
158
|
-
ANALYZE VERBOSE "public"."
|
|
158
|
+
ANALYZE VERBOSE "public"."visits_202510";
|
|
159
159
|
|
|
160
160
|
ANALYZE VERBOSE "public"."visits_intermediate";
|
|
161
161
|
```
|
|
@@ -219,14 +219,14 @@ WHERE
|
|
|
219
219
|
Back up and drop older partitions each day, month, or year.
|
|
220
220
|
|
|
221
221
|
```sh
|
|
222
|
-
pg_dump -c -Fc -t <table>
|
|
223
|
-
psql -c "DROP TABLE <table>
|
|
222
|
+
pg_dump -c -Fc -t <table>_202509 $PGSLICE_URL > <table>_202509.dump
|
|
223
|
+
psql -c "DROP TABLE <table>_202509" $PGSLICE_URL
|
|
224
224
|
```
|
|
225
225
|
|
|
226
226
|
If you use [Amazon S3](https://aws.amazon.com/s3/) for backups, [s3cmd](https://github.com/s3tools/s3cmd) is a nice tool.
|
|
227
227
|
|
|
228
228
|
```sh
|
|
229
|
-
s3cmd put <table>
|
|
229
|
+
s3cmd put <table>_202509.dump s3://<s3-bucket>/<table>_202509.dump
|
|
230
230
|
```
|
|
231
231
|
|
|
232
232
|
## Schema Updates
|
|
@@ -269,7 +269,7 @@ SELECT * FROM
|
|
|
269
269
|
WHERE
|
|
270
270
|
user_id = 123 AND
|
|
271
271
|
-- for performance
|
|
272
|
-
created_at >= '
|
|
272
|
+
created_at >= '2025-09-01' AND created_at < '2025-09-02'
|
|
273
273
|
```
|
|
274
274
|
|
|
275
275
|
For this to be effective, ensure `constraint_exclusion` is set to `partition` (the default value) or `on`.
|
|
@@ -13,7 +13,11 @@ module PgSlice
|
|
|
13
13
|
assert_table(table)
|
|
14
14
|
|
|
15
15
|
future = options[:future]
|
|
16
|
+
# TODO uncomment in 0.8.0
|
|
17
|
+
# abort "--future cannot be negative" if future < 0
|
|
16
18
|
past = options[:past]
|
|
19
|
+
# TODO uncomment in 0.8.0
|
|
20
|
+
# abort "--past cannot be negative" if past < 0
|
|
17
21
|
tablespace = options[:tablespace]
|
|
18
22
|
range = (-1 * past)..future
|
|
19
23
|
|
|
@@ -27,7 +31,7 @@ module PgSlice
|
|
|
27
31
|
queries = []
|
|
28
32
|
|
|
29
33
|
if needs_comment
|
|
30
|
-
queries << "COMMENT ON TRIGGER #{quote_ident(trigger_name)} ON #{quote_table(table)} IS
|
|
34
|
+
queries << "COMMENT ON TRIGGER #{quote_ident(trigger_name)} ON #{quote_table(table)} IS #{quote("column:#{field},period:#{period},cast:#{cast}")};"
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
# today = utc date
|
data/lib/pgslice/cli/fill.rb
CHANGED
|
@@ -74,7 +74,7 @@ module PgSlice
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
while starting_id < max_source_id
|
|
77
|
-
where = "#{quote_ident(primary_key)} > #{starting_id} AND #{quote_ident(primary_key)} <= #{starting_id + batch_size}"
|
|
77
|
+
where = "#{quote_ident(primary_key)} > #{quote(starting_id)} AND #{quote_ident(primary_key)} <= #{quote(starting_id + batch_size)}"
|
|
78
78
|
if starting_time
|
|
79
79
|
where << " AND #{quote_ident(field)} >= #{sql_date(starting_time, cast)} AND #{quote_ident(field)} < #{sql_date(ending_time, cast)}"
|
|
80
80
|
end
|
data/lib/pgslice/cli/prep.rb
CHANGED
|
@@ -55,7 +55,7 @@ module PgSlice
|
|
|
55
55
|
# add comment
|
|
56
56
|
cast = table.column_cast(column)
|
|
57
57
|
queries << <<~SQL
|
|
58
|
-
COMMENT ON TABLE #{quote_table(intermediate_table)} IS
|
|
58
|
+
COMMENT ON TABLE #{quote_table(intermediate_table)} IS #{quote("column:#{column},period:#{period},cast:#{cast},version:#{version}")};
|
|
59
59
|
SQL
|
|
60
60
|
else
|
|
61
61
|
queries << <<~SQL
|
|
@@ -85,7 +85,7 @@ module PgSlice
|
|
|
85
85
|
|
|
86
86
|
cast = table.column_cast(column)
|
|
87
87
|
queries << <<~SQL
|
|
88
|
-
COMMENT ON TRIGGER #{quote_ident(trigger_name)} ON #{quote_table(intermediate_table)} IS
|
|
88
|
+
COMMENT ON TRIGGER #{quote_ident(trigger_name)} ON #{quote_table(intermediate_table)} IS #{quote("column:#{column},period:#{period},cast:#{cast}")};
|
|
89
89
|
SQL
|
|
90
90
|
end
|
|
91
91
|
|
data/lib/pgslice/cli/swap.rb
CHANGED
|
@@ -20,7 +20,7 @@ module PgSlice
|
|
|
20
20
|
queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_schema"])}.#{quote_ident(sequence["sequence_name"])} OWNED BY #{quote_table(table)}.#{quote_ident(sequence["related_column"])};"
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
queries.unshift("SET LOCAL lock_timeout = #{
|
|
23
|
+
queries.unshift("SET LOCAL lock_timeout = #{quote(options[:lock_timeout])};")
|
|
24
24
|
|
|
25
25
|
run_queries(queries)
|
|
26
26
|
end
|
data/lib/pgslice/helpers.rb
CHANGED
|
@@ -77,7 +77,7 @@ module PgSlice
|
|
|
77
77
|
begin
|
|
78
78
|
execute(query)
|
|
79
79
|
rescue PG::ServerError => e
|
|
80
|
-
abort
|
|
80
|
+
abort "#{e.class.name}: #{e.message}"
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
83
|
log_sql
|
|
@@ -102,8 +102,17 @@ module PgSlice
|
|
|
102
102
|
else
|
|
103
103
|
fmt = "%Y-%m-%d"
|
|
104
104
|
end
|
|
105
|
-
str =
|
|
106
|
-
add_cast
|
|
105
|
+
str = quote(time.strftime(fmt))
|
|
106
|
+
if add_cast
|
|
107
|
+
case cast
|
|
108
|
+
when "date", "timestamptz"
|
|
109
|
+
"#{str}::#{cast}"
|
|
110
|
+
else
|
|
111
|
+
abort "Invalid cast"
|
|
112
|
+
end
|
|
113
|
+
else
|
|
114
|
+
str
|
|
115
|
+
end
|
|
107
116
|
end
|
|
108
117
|
|
|
109
118
|
def name_format(period)
|
|
@@ -157,8 +166,12 @@ module PgSlice
|
|
|
157
166
|
PG::Connection.quote_ident(value)
|
|
158
167
|
end
|
|
159
168
|
|
|
160
|
-
def
|
|
161
|
-
|
|
169
|
+
def quote(value)
|
|
170
|
+
if value.is_a?(Numeric)
|
|
171
|
+
value
|
|
172
|
+
else
|
|
173
|
+
connection.escape_literal(value)
|
|
174
|
+
end
|
|
162
175
|
end
|
|
163
176
|
|
|
164
177
|
def quote_table(table)
|
data/lib/pgslice/table.rb
CHANGED
|
@@ -166,7 +166,6 @@ module PgSlice
|
|
|
166
166
|
execute(query, [trigger_name, quote_table])[0]
|
|
167
167
|
end
|
|
168
168
|
|
|
169
|
-
# legacy
|
|
170
169
|
def fetch_settings(trigger_name)
|
|
171
170
|
needs_comment = false
|
|
172
171
|
trigger_comment = fetch_trigger(trigger_name)
|
|
@@ -194,6 +193,10 @@ module PgSlice
|
|
|
194
193
|
needs_comment = true
|
|
195
194
|
end
|
|
196
195
|
|
|
196
|
+
unless ["date", "timestamptz"].include?(cast)
|
|
197
|
+
abort "Invalid cast"
|
|
198
|
+
end
|
|
199
|
+
|
|
197
200
|
version ||= trigger_comment ? 1 : 2
|
|
198
201
|
declarative = version > 1
|
|
199
202
|
|
|
@@ -202,26 +205,24 @@ module PgSlice
|
|
|
202
205
|
|
|
203
206
|
protected
|
|
204
207
|
|
|
208
|
+
def abort(message)
|
|
209
|
+
PgSlice::CLI.instance.send(:abort, message)
|
|
210
|
+
end
|
|
211
|
+
|
|
205
212
|
def execute(*args)
|
|
206
213
|
PgSlice::CLI.instance.send(:execute, *args)
|
|
207
214
|
end
|
|
208
215
|
|
|
209
|
-
def
|
|
210
|
-
PgSlice::CLI.instance.send(:
|
|
216
|
+
def quote(value)
|
|
217
|
+
PgSlice::CLI.instance.send(:quote, value)
|
|
211
218
|
end
|
|
212
219
|
|
|
213
220
|
def quote_ident(value)
|
|
214
|
-
|
|
221
|
+
PgSlice::CLI.instance.send(:quote_ident, value)
|
|
215
222
|
end
|
|
216
223
|
|
|
217
|
-
def sql_date(
|
|
218
|
-
|
|
219
|
-
fmt = "%Y-%m-%d %H:%M:%S UTC"
|
|
220
|
-
else
|
|
221
|
-
fmt = "%Y-%m-%d"
|
|
222
|
-
end
|
|
223
|
-
str = escape_literal(time.strftime(fmt))
|
|
224
|
-
add_cast ? "#{str}::#{cast}" : str
|
|
224
|
+
def sql_date(*args)
|
|
225
|
+
PgSlice::CLI.instance.send(:sql_date, *args)
|
|
225
226
|
end
|
|
226
227
|
end
|
|
227
228
|
end
|
data/lib/pgslice/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pgslice
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
@@ -9,6 +9,20 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: cgi
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
12
26
|
- !ruby/object:Gem::Dependency
|
|
13
27
|
name: pg
|
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -77,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
91
|
- !ruby/object:Gem::Version
|
|
78
92
|
version: '0'
|
|
79
93
|
requirements: []
|
|
80
|
-
rubygems_version:
|
|
94
|
+
rubygems_version: 4.0.3
|
|
81
95
|
specification_version: 4
|
|
82
96
|
summary: Postgres partitioning as easy as pie
|
|
83
97
|
test_files: []
|