2010-08-13 5 views
1

J'utilise Rails Fixtures pour charger des données de test dans ma base de données et j'ai accidentellement introduit une clé étrangère hors de portée. À ma grande surprise, la base de données l'a acceptée malgré les contraintes d'intégrité référentielle (qui fonctionnent). J'ai essayé avec PostgreSQL et avec MySQL InnoDB et les deux ont permis.Les bases de données permettent de mauvaises clés étrangères des Rails Fixtures

Exemple:

ayant dans la base de données "Flavours" cinque une clé primaire numérique (id), 5 entrées (1 à 5). Je peux présenter des données incorrectes faire:

Icecream_1: nom: ma crème glacée flavour_id: 6

Comment est-il possible que les installations de chargement vont autour de mes contraintes de base de données?

Merci.


Voici deux tables. Ayant 200 user_types (fausses données) j'ai pu introduire un utilisateur avec user_type_id 201 mais seulement des fixtures, pgAdmin l'interdit.

CREATE SEQUENCE user_types_id_seq; 
CREATE TABLE user_types (
id SMALLINT 
    NOT NULL 
    DEFAULT NEXTVAL('user_types_id_seq'), 
name VARCHAR(45) 
    NOT NULL 
    UNIQUE, 
PRIMARY KEY (id)); 

CREATE SEQUENCE users_id_seq; 
CREATE TABLE users (
id BIGINT 
    NOT NULL 
    DEFAULT NEXTVAL('users_id_seq'), 
user_type_id SMALLINT 
    NOT NULL 
    REFERENCES user_types (id) ON DELETE CASCADE ON UPDATE CASCADE, 
PRIMARY KEY (id)); 


--------- 

Fixture 

<% for i in (1..201) %> 

user_<%= i %>: 
    id: <%= i %> 
    user_type_id: <%= i %> 
<% end %> 

Et comme je l'ai dit, innoDb et postgresql ont tous deux accepté la mauvaise clé.

Merci

+0

Il pourrait y avoir une idée là-bas. –

+0

Voir la mise à jour. –

Répondre

1

PostgreSQL n'accepte pas les données corrompues, ne vous inquiétez pas. En MySQL tout dépend du moteur (doit être innoDB) et des paramètres (connexion) du paramètre foreign_key_checks.

A quoi ressemblent vos tableaux et vos contraintes? Vérifiez pgAdmin (ou un autre client) et vider le morceau de datamodel pertinent ici, que nous pouvons vous aider.

pgAdmin l'interdit.

Non, votre base de données PostgreSQL l'interdit. pgAdmin est juste un client et il envoie seulement une requête à la base de données. La base de données effectue des vérifications, FK a été violé et renvoie une erreur.

On dirait que vous travaillez sur la mauvaise base de données (pas de FK ou MySQL avec le mauvais moteur et/ou les paramètres), PostgreSQL fonctionne très bien avec un FK.

0

Je suis d'accord avec Frank. Votre base de données de test pour PostgreSQL n'est probablement pas configurée correctement. Vous avez oublié de créer les contraintes FK ou vous les avez désactivées.

Le fait que vous ayez une erreur dans pgAdmin indique que vous travaillez avec une base de données différente depuis pgAdmin et votre script de test. En ce qui concerne MySQL, je rechercherais un mauvais moteur par défaut dans la base de données de test ou si vous avez oublié d'y créer des contraintes FK (notez que vous n'obtiendrez pas d'erreur si vous créez une contrainte FK avec un moteur qui ne prend pas en charge l'intégrité référentielle sur MySQL)

0

Vérifiez les définitions de table dans votre base de données de test. IIRC, "rake db: test: prepare" ne conserve pas la fidélité lors de la création des tables dans la base de données de test.

0

Merci à tous pour votre réponse.

Quelqu'un au forum de ruby ​​l'a compris. On dirait que les déclencheurs qui appliquent RI sont désactivés avant le chargement des appareils.

Je ne sais pas pourquoi mais cela résout le mystère. Pourrions-nous jeter un coup d'oeil à vos définitions de table?

+0

Ces "déclencheurs" ne sont pas les déclencheurs de base de données, il est impossible dans PostgreSQL de désactiver les contraintes de clés étrangères (déclencheurs a.k.a.). Votre base de données a FK ou elle n'a pas de FK, il n'y a pas quelque chose comme un FK désactivé. –

+0

Je pense que vous trouverez que les tables de MySQL qui appliquent l'intégrité référentielle doivent être créées avec la clause ENGINE = INNODB. Si ce n'est pas le cas, ils peuvent stocker les contraintes mais ils n'agissent pas sur eux. –

+0

Oui Brian vous avez raison, toutes les tables dans MySQL ont ENGINE = INNODB. – Ferreira

Questions connexes