Closed bjeanes closed 1 year ago
My workaround in the meantime:
# lib/tasks/db.rake
namespace :db do
# Clickhouse adapter does not raise the right exception when there is no DB, which breaks
# `db:prepare` task. I don't want to monkeypatch broadly in our app on this driver, so
# this task is a workaround that only applies in this db setup context.
#
# https://github.com/PNixx/clickhouse-activerecord/issues/91
task :fix_clickhouse do
module ClickhouseAdapterNoDbFix
def process_response(res)
super(res)
rescue ActiveRecord::ActiveRecordError
case res.body
when /DB::Exception:.*\(UNKNOWN_DATABASE\)/
raise ActiveRecord::NoDatabaseError
when /DB::Exception:.*\(DATABASE_ALREADY_EXISTS\)/
raise ActiveRecord::DatabaseAlreadyExists
else
raise
end
end
end
ActiveRecord::ConnectionAdapters::Clickhouse::SchemaStatements.prepend(ClickhouseAdapterNoDbFix)
end
end
Rake::Task['db:load_config'].enhance ['db:fix_clickhouse']
Currently, when a database does not exist and a query is executed, a generic
ActiveRecord::ActiveRecordError
is raised.Other adapters use
ActiveRecord::NoDatabaseError
and thedb:prepare
Rake task depends on this fact to do the right thing (and has done since at least Rails 6, though I suspect earlier).Here is what is raised with
postgres
adapter on main DB, when trying to migrate or query against a non-existent DB:And clickhouse with current version of this adapter:
Similarly,
ActiveRecord::DatabaseAlreadyExists
should be raised when the database already exists and it Rails is attempting to create it. This exception is caught to make the Rake task seem idempotent.