В моем приложении на Rails 6 я создаю таблицу, которая, как я знаю, станет большой. Поэтому я делю его по месяцам, используя pg_partman . Он размещен на Heroku, поэтому я следовал их инструкциям . Миграция выглядит примерно так:
class CreateReceipts < ActiveRecord::Migration[6.0]
def change
reversible do |dir|
dir.up do
execute <<-SQL
create extension pg_partman;
SQL
end
dir.down do
execute <<-SQL
drop extension pg_partman;
SQL
end
end
create_table(
:receipts,
# Partitioning requires the primary key includes the column we're partitioning by.
primary_key: [:id, :created_at],
options: 'partition by range (created_at)'
) do |t|
# When using the primary key option, it ignores id: true. Make the ID column manually.
t.column :id, :bigserial, null: false
t.references :customer, null: false, foreign_key: true
t.integer :thing, null: false
t.text :stuff, null: false
t.timestamps
end
reversible do |dir|
dir.up do
execute <<-SQL
select create_parent('public.receipts', 'created_at', 'native', 'monthly');
SQL
end
dir.down do
# Dropping receipts undoes all the partitioning, except the template table.
drop_table(:template_public_receipts)
end
end
end
end
class Receipt < ApplicationRecord
# The composite primary key is only for partitioning.
self.primary_key = 'id'
# Unfortunately, partitioning gets confused if we add another unique index.
# So we must enforce ID uniqueness in the model.
validates :id, uniqueness: true
end
Немного странно с первичным ключом, но он отлично работает локально. Heroku Postgres имеет расширение pg_partman, поэтому производство в порядке.
Проблема в HerokuCI. Я использую рекомендуемую базу данных in-dyno add on. У него нет pg_partman
.
-----> Preparing test database
Running: rake db:schema:load_if_ruby
db:schema:load_if_ruby completed (6.17s)
Running: rake db:structure:load_if_sql
set_config
------------
(1 row)
psql:/app/db/structure.sql:16: ERROR: could not open extension control file "/app/.indyno/vendor/postgresql/share/extension/pg_partman.control": No such file or directory
rake aborted!
failed to execute:
Я бы предпочел не подключать полную базу данных к CI только для этого. И кажется странным жестко кодировать разделы pg_partman в схеме, хотя хорошо, чтобы тесты были как можно ближе к производству.
Есть ли альтернативный подход?