我尝试使用Heroku的CI运行我的Rails应用程序测试,但在尝试加载structure.sql
文件时遇到了问题。< / p>
-----> Preparing test database
Running: rake db:schema:load_if_ruby
db:schema:load_if_ruby completed (3.24s)
Running: rake db:structure:load_if_sql
psql:/app/db/structure.sql:28: ERROR: must be owner of extension plpgsql
rake aborted!
failed to execute:
psql -v ON_ERROR_STOP=1 -q -f /app/db/structure.sql d767koa0m1kne1
Please check the output above for any errors and make sure that `psql` is installed in your PATH and has proper permissions.
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/postgresql_database_tasks.rb:108:in `run_cmd'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/postgresql_database_tasks.rb:80:in `structure_load'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/database_tasks.rb:223:in `structure_load'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/database_tasks.rb:236:in `load_schema'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/database_tasks.rb:255:in `block in load_schema_current'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/database_tasks.rb:304:in `block in each_current_configuration'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/database_tasks.rb:303:in `each'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/database_tasks.rb:303:in `each_current_configuration'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/tasks/database_tasks.rb:254:in `load_schema_current'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/railties/databases.rake:290:in `block (3 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.1/lib/active_record/railties/databases.rake:294:in `block (3 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
Tasks: TOP => db:structure:load
(See full trace by running task with --trace)
!
! Could not prepare database for test
!
这里的相关行是:
psql:/app/db/structure.sql:28:ERROR:必须是扩展程序plpgsql的所有者 耙子流产了!
Structure.sql包含以下行:
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
有关如何使用Heroku的CI的任何想法?
答案 0 :(得分:4)
结束覆盖COMMENT ON ...
以删除namespace :db do
namespace :structure do
task dump: [:environment, :load_config] do
filename = ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
sql = File.read(filename).each_line.grep_v(/\ACOMMENT ON EXTENSION.+/).join
File.write(filename, sql)
end
end
end
声明:
private void WaitChangeStatus(object sender, DoWorkEventArgs e)
{
while (!e.Cancel)
{
SmartCardErrorCode result;
// Obtain a lock when we use the context pointer, which may be modified in the Dispose() method.
lock (this)
{
if (!this.HasContext)
{
return;
}
// This thread will be executed every 1000ms.
// The thread also blocks for 1000ms, meaning
// that the application may keep on running for
// one extra second after the user has closed the Main Form.
result = (SmartCardErrorCode)UnsafeNativeMethods.GetStatusChange(this.context, 1000, this.states, (uint)this.states.Length);
}
if ((result == SmartCardErrorCode.Timeout))
{
// Time out has passed, but there is no new info. Just go on with the loop
continue;
}
else if (result != SmartCardErrorCode.Succeeed)
{
// TODO OnExceptionRaised
continue;
}
for (int i = 0; i <= this.states.Length - 1; i++)
{
// Check if the state changed from the last time.
if ((this.states[i].EventState & CardState.Changed) == CardState.Changed)
{
// Check what changed.
SmartCardState state = SmartCardState.None;
if ((this.states[i].EventState & CardState.Present) == CardState.Present
&& (this.states[i].CurrentState & CardState.Present) != CardState.Present)
{
// The card was inserted.
state = SmartCardState.Inserted;
}
else if ((this.states[i].EventState & CardState.Empty) == CardState.Empty
&& (this.states[i].CurrentState & CardState.Empty) != CardState.Empty)
{
// The card was ejected.
state = SmartCardState.Ejected;
}
if (state != SmartCardState.None && this.states[i].CurrentState != CardState.Unaware)
{
SmartCardEventArgs args = new SmartCardEventArgs();
args.Manager = this;
switch(state)
{
case SmartCardState.Inserted:
{
// Checa o ATR para monitorar apenas DESFire EV1
if (OnCardInserted != null)
{
// Obtém o ATR
byte[] atr = this.GetAtr(this.states[i].ATRBytes, this.states[i].ATRLength);
// Cria SmartCard object and associa ao EventArgs
SmartCard card = new SmartCard(atr);
args.Card = card;
// Dispara Evento
OnCardInserted(this, args);
}
break;
}
case SmartCardState.Ejected:
{
if (OnCardRemoved != null)
{
OnCardRemoved(this, args);
}
break;
}
default:
{
// TODO Log
// Null to force Garbage Collection
args = null;
break;
}
}
}
//Update the current state for the next time they are checked.
this.states[i].CurrentState = this.states[i].EventState;
}
}
}
}
答案 1 :(得分:3)
另一种解决方法是添加类似
的内容if Rails.env.development?
ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = ["-v", "ON_ERROR_STOP=0"]
end
在执行db:structure:load
之前初始化/任务管道中的任何位置。
答案 2 :(得分:2)
如果Kyle的解决方案不够,并且错误不是仅由扩展评论引起的,而是由实际扩展安装引起的,您仍然可以采取艰难的方式并将其添加到初始化程序中:
# This is a temporary workaround for the Rails issue #29049.
# It could be safely removed when the PR #29110 got merged and released
# to use instead IGNORE_PG_LOAD_ERRORS=1.
module ActiveRecord
module Tasks
class PostgreSQLDatabaseTasks
ON_ERROR_STOP_1 = 'ON_ERROR_STOP=0'.freeze
end
end
end
注意:这不是Heroku特有的,而是更广泛的Rails 5.1问题
答案 3 :(得分:0)
有两个解决方案。如前所述,首先禁用ON_ERROR_STOP
功能。无论环境如何,它都会有所帮助。自定义耙任务:
namespace :db do
namespace :structure do
# This little task is a workaround for a problem introduced in Rails5. Most specificaly here
# https://github.com/rails/rails/blob/5-1-stable/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb#L77
# When psql encounters an error during loading of the structure it exits at once with error code 1.
# And this happens on heroku. It renders review apps and heroku CI unusable if you use a structure instead of a schema.
# Why?
# Our `db/structure.sql` contains entries like `CREATE EXTENSION` or `COMMENT ON EXTENSION`.
# Zylion of extensions on heroku are loaded in template0, so "our" db also has them, but because of that
# only a superuser (or owner of template0) has access to them - not our heroku db user. For that reason
# we can neither create an extension (it already exists, but that is not a problem, because dump contains IF NOT EXIST)
# nor comment on it (and comments don't have IF NOT EXIST directive). And that's an error which could be safely ignored
# but which stops loading of the rest of the structure.
desc "Disable exit-on-error behaviour when loading db structure in postgresql"
task disable_errors: :environment do
ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = ["-v", "ON_ERROR_STOP=0"]
end
end
end
# And use it like so:
bin/rails db:structure:disable_errors db:structure:load
在我看来,另一种选择(如果仅涉及Heroku则更好)是在in-dyno
计划(https://devcenter.heroku.com/articles/heroku-ci-in-dyno-databases)中使用PostgreSQL,这基本上是一个位于dyno中的数据库实例,因此完全访问它。同样,测试套件应该明显更快,因为我们使用本地主机连接,而不是通过网络。要启用它,请将您的app.json
内容更改为具有以下条目:
{
"environments": {
"test": {
"addons": [
"heroku-postgresql:in-dyno"
]
}
}
}