web-dev-qa-db-fra.com

ActiveRecord :: StatementInvalid: PG InFailedSqlTransaction

J'essaie de créer un objet ActiveRecord.Mais je reçois cette erreur lors de sa création.

(0.1ms)  ROLLBACK
ActiveRecord::StatementInvalid: PG::InFailedSqlTransaction: ERROR:  current transaction is       aborted, commands ignored until end of transaction block

Toutes les idées concernant le problème.

58
untwal

Aucune des autres réponses ne résout le problème cause fondamentale du problème.

Le problème est que lorsque Postgres déclenche une exception, il empoisonne les transactions futures sur la même connexion.

Le correctif consiste à annuler la transaction en cause:

begin
  ActiveRecord...do something...
rescue Exception => e
  puts "SQL error in #{ __method__ }"
  ActiveRecord::Base.connection.execute 'ROLLBACK'

  raise e
end

Voir référence .

85
B Seven

J'ai eu ce problème. Il suffit de redémarrer le serveur Rails et cela devrait fonctionner

78
Furkan Ayhan

Ce problème se produisait dans mon environnement de test et était dû au fait que chaque test était encapsulé dans sa propre transaction.

J'utilisais la gemme database_cleaner et je l'ai configurée pour NE PAS encapsuler les tests dans une transaction s'ils utilisent du javascript. Donc, pour résoudre le problème, j'ai ajouté js: true à chaque spécification qui était à l'origine de ce problème. (Même si les spécifications n’utilisaient pas javascript, c’était le moyen le plus pratique d’éviter que les tests ne soient encapsulés dans une transaction. Je suis sûr qu’il existe moins de façons de le faire, cependant).

Pour référence, voici le fichier database_cleaner config de spec/support/database_cleaner.rb:

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.clean_with :deletion
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :deletion
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

Si vous n'utilisez pas database_cleaner, la raison pour laquelle les tests seraient encapsulés dans des transactions serait probablement que l'option use_transactional_fixtures est définie sur true dans spec/spec_helper.rb. Essayez de le définir sur false.

14
Teddy Widom

vous pouvez voir ce qui se passe réellement dans le journal postgresql, je passe beaucoup de temps à creuser ce problème et enfin à découvrir que nous utilisons abusivement la gemme causant une erreur PG. 

https://github.com/seamusabshere/upsert/issues/39

7
William Herry

J'ai rencontré cette erreur lors de la référence à une colonne de mes spécifications qui n'existe plus. Assurez-vous que votre base de données est à jour et que votre code ne s'attend pas à une colonne qui n'existe pas.

5
lobati

Dans mon cas, j'ai reçu cette erreur simplement parce que je n'avais pas raté ma base de test. 

2
nfriend21

Problème:

  1. Le programme exécute une instruction SQL incorrecte. Une instruction SQL incorrecte est à l'origine du problème.
  2. Le programme ne ROLLBACK ou RELEASE SAVEPOINT pas immédiatement après une instruction SQL incorrecte.
  3. Le programme exécute les instructions SQL après une instruction SQL incorrecte.
  4. PostgreSQL lance ERROR: la transaction en cours est abandonnée, les commandes sont ignorées jusqu'à la fin du bloc de transaction. 

Solution:

Recherchez l'instruction SQL incorrecte et corrigez-la . Si vous ne souhaitez pas corriger l'instruction SQL, utilisez ROLLBACK ou RELEASE SAVEPOINT après une instruction SQL incorrecte.

2
John Doe

Dans mon cas, la configuration de Postgres à /usr/local/var/postgres/postgresql.conf avait le type de données comme format international dmy

Changer le type de données au format américain de mdy a résolu ce problème pour moi.

2
Winsor

Avait un problème similaire après la mise à niveau de Rails de 4.2.2 à 4.2.5, je devais mettre à niveau pg gem et le problème a commencé à se produire

9) WorkPolicy#is_publicly_viewable? is publicly visible hides work if deleted
     Failure/Error: before { DatabaseCleaner.clean_with :deletion }
     ActiveRecord::StatementInvalid:
       PG::InFailedSqlTransaction: ERROR:  current transaction is aborted, commands ignored until end of transaction block
       :             SELECT tablename
                   FROM pg_tables
                   WHERE schemaname = ANY (current_schemas(false))

Teddy Widom Réponse a raison en ce sens, pour résumer le problème:

Parfois, lorsque vous utilisez DatabaseCleaner.clean_with :deletion, vous pouvez interférer avec une transaction PostgreSQL. 

Donc, la solution pour moi était de remplacer DatabaseCleaner.clean_with :deletion dans certaines parties des tests où cela était causé par DatabaseCleaner.clean_with :truncation

Encore une chose pour googler les gens. Si vous remarquez cette trace de pile:

An error occurred in an `after(:context)` hook.
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "table_rows" does not exist
LINE 1: ...ion_schema.tables WHERE table_schema = 'test' AND table_rows...
^

... cela peut être causé par ce problème

0
equivalent8

J'ai ce problème. Et j’ai découvert que c’était ma requête . Cela signifie que j’interroge avec association sans spécifier de colonne de table . Ex:

class Holiday < ApplicationRecord
     belongs_to :company
end

class Company < ApplicationRecord
    has_many :timeoffs
end

Dans le modèle de vacances, je demande

company.timeoffs.where("(start_date <= ? and end_date >= ?) and id != ?", begin_date, begin_date, 1)

L'erreur se produit parce que je n'ai pas spécifié la table id Elle a fonctionné pour moi après avoir modifié le code en

company.timeoffs.where("(start_date <= ? and end_date >= ?) and time_offs.id != ?", begin_date, begin_date, 1)
0
pdkpro