rails proyecto new myapp digitalocean datos crear conectar con ruby-on-rails postgresql

ruby-on-rails - proyecto - rails new myapp postgresql



Error de descarte de Rails+Postgres: otros usuarios están accediendo a la base de datos (12)

Tengo una aplicación de rieles sobre Postgres.

Tengo dos servidores: uno para probar y el otro para producción.

Muy a menudo necesito clonar el DB de producción en el servidor de prueba.

El comando que estoy ejecutando a través de Vlad es:

rake RAILS_ENV=''test_server'' db:drop db:create

El problema que tengo es que recibo el siguiente error:

ActiveRecord::StatementInvalid: PGError: ERROR: database <database_name> is being accessed by other users DROP DATABASE IF EXISTS <database_name>

Esto sucede si alguien ha accedido a la aplicación a través de la web recientemente (postgres mantiene abierta una "sesión")

¿Hay alguna forma de que pueda finalizar las sesiones en la base de datos Postgres?

Gracias.

Editar

Puedo eliminar la base de datos usando la interfaz de phppgadmin, pero no con la tarea de rake.

¿Cómo puedo replicar la caída de phppgadmin con una tarea de rake?


Aquí hay una forma rápida de eliminar todas las conexiones a su base de datos postgres.

sudo kill -9 `ps -u postgres -o pid`

Advertencia: esto matará todos los procesos en ejecución que el usuario de postgres haya abierto, así que asegúrese de hacer esto primero.


Cuando usamos el método "matar procesos" desde arriba, el db: drop estaba fallando (si: kill_postgres_connections era un requisito previo). Creo que fue porque la conexión que ese comando de rake estaba usando estaba siendo asesinada. En cambio, estamos usando un comando sql para soltar la conexión. Esto funciona como un prerrequisito para db: drop, evita el riesgo de matar procesos a través de un comando bastante complejo, y debería funcionar en cualquier sistema operativo (gentoo requiere una sintaxis diferente para kill ).

cmd = %(psql -c "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE procpid <> pg_backend_pid();" -d ''#{db_name}'')

Aquí hay una tarea de rake que lee el nombre de la base de datos de database.yml y ejecuta un comando mejorado (en mi humilde opinión). También agrega db: kill_postgres_connections como prerrequisito para db: drop. Incluye una advertencia que grita después de actualizar los rieles, lo que indica que este parche ya no es necesario.

ver: https://gist.github.com/4455341 , referencias incluidas


Deje que su aplicación cierre la conexión cuando esté lista. PostgreSQL no mantiene las conexiones abiertas, es la aplicación que mantiene la conexión.


Es probable que Rails se conecte a la base de datos para soltarlo, pero cuando inicia sesión a través de phppgadmin, está iniciando sesión a través de la plantilla1 o la base de datos postgres, por lo que no se verá afectado.


Escribí una gema llamada pgreset que matará automáticamente las conexiones a la base de datos en cuestión cuando ejecute rake db: drop (o db: reset, etc.). Todo lo que tienes que hacer es agregarlo a tu Gemfile y este problema debería desaparecer. En el momento de escribir estas líneas, funciona con Rails 4 en adelante y ha sido probado en Postgres 9.x. El código fuente está disponible en github para cualquier persona interesada.

gem ''pgreset''


Si matas las conexiones postgresql en ejecución para tu aplicación, puedes ejecutar db: drop it fine. Entonces, ¿cómo matar esas conexiones? Uso la siguiente tarea de rake:

# lib/tasks/kill_postgres_connections.rake task :kill_postgres_connections => :environment do db_name = "#{File.basename(Rails.root)}_#{Rails.env}" sh = <<EOF ps xa / | grep postgres: / | grep #{db_name} / | grep -v grep / | awk ''{print $1}'' / | xargs kill EOF puts `#{sh}` end task "db:drop" => :kill_postgres_connections

Eliminar las conexiones de debajo de los rieles a veces hará que estalle la próxima vez que intentes cargar una página, pero volver a cargarla restablece la conexión.


Solo asegúrese de que haya salido de la consola de rieles en cualquier ventana de terminal abierta y haya salido del servidor de rieles ... este es uno de los errores más comunes cometidos por personas


Tuve un error similar al decir que 1 usuario estaba usando la base de datos, ¡me di cuenta de que era YO! Apagué el servidor de mis raíles y luego hice el comando rake: drop y ¡funcionó!


Una manera más fácil y más actualizada es: 1. Usar ps -ef | grep postgres ps -ef | grep postgres para encontrar la conexión # 2. sudo kill -9 "# of the connection

Nota: Puede haber un PID idéntico. Matar a uno mata a todos.


Uso la siguiente tarea de rake para anular el método Rails drop_database .

lib/database.rake

require ''active_record/connection_adapters/postgresql_adapter'' module ActiveRecord module ConnectionAdapters class PostgreSQLAdapter < AbstractAdapter def drop_database(name) raise "Nah, I won''t drop the production database" if Rails.env.production? execute <<-SQL UPDATE pg_catalog.pg_database SET datallowconn=false WHERE datname=''#{name}'' SQL execute <<-SQL SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = ''#{name}''; SQL execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}" end end end end


Usted puede simplemente monopatchear el código de ActiveRecord que realiza la caída.

Para Rails 3.x:

# lib/tasks/databases.rake def drop_database(config) raise ''Only for Postgres...'' unless config[''adapter''] == ''postgresql'' Rake::Task[''environment''].invoke ActiveRecord::Base.connection.select_all "select pg_terminate_backend(pg_stat_activity.pid) from pg_stat_activity where datname=''#{config[''database'']}'' AND state=''idle'';" ActiveRecord::Base.establish_connection config.merge(''database'' => ''postgres'', ''schema_search_path'' => ''public'') ActiveRecord::Base.connection.drop_database config[''database''] end

Para Rails 4.x:

# config/initializers/postgresql_database_tasks.rb module ActiveRecord module Tasks class PostgreSQLDatabaseTasks def drop establish_master_connection connection.select_all "select pg_terminate_backend(pg_stat_activity.pid) from pg_stat_activity where datname=''#{configuration[''database'']}'' AND state=''idle'';" connection.drop_database configuration[''database''] end end end end

(de: http://www.krautcomputing.com/blog/2014/01/10/how-to-drop-your-postgres-database-with-rails-4/ )


Verifique si la consola de sus raíles o el servidor se está ejecutando en otra pestaña y luego

detener el servidor y la consola de los rieles.

entonces corre

rake db:drop