2012-01-21 2 views
0

Je souhaite utiliser une variable SQL auto-incrémentée en tant que clé étrangère. Le code est écrit en Python/SQL (quelle est la bonne façon de le dire?) Cependant, sauf si je mets un nombre réel, j'obtiens des erreurs de contrainte de clé étrangère.Utilisation de la variable AutoIncrement en tant que clé étrangère - erreur de contrainte de clé étrangère get

J'ai lu plusieurs messages au sujet de ces erreurs et a tenté d'utiliser les informations ...

Voici mes deux tables. Table1 est le haut, Table2 est le bas. ID est la clé étrangère. J'ai mis le numéro 1 dans mon code afin d'éviter les erreurs.

+----+------+-------+ 
| id | name | class | 
+----+------+-------+ 
| 1 | ONE | TWO | 
| 2 | ONE | TWO | 
| 3 | ONE | TWO | 
| 4 | ONE | TWO | 
+----+------+-------+ 

mysql> select * from table2; 

+-----+------+-------+----+ 
| par | name | class | ID | 
+-----+------+-------+----+ 
| 1 | SSS | CAR | 1 | 
| 2 | SSS | CAR | 1 | 
+-----+------+-------+----+ 

Et voici le code

sql= """CREATE TABLE IF NOT EXISTS table1 (
     `ID` integer NOT NULL AUTO_INCREMENT, 
    `name` varchar(30) default NULL, 
    `class` varchar(20) default NULL, 
     PRIMARY KEY (`ID`) 
     )""" 
cursor.execute(sql) 

sql2 = """CREATE TABLE IF NOT EXISTS table2 (
    `par` integer NOT NULL AUTO_INCREMENT, 
    `name` varchar(30) default NULL, 
    `class` varchar(20) default NULL, 
    `ID` integer NOT NULL, 
    FOREIGN KEY (ID) REFERENCES table1 (ID), 
    PRIMARY KEY (par) 
)"""   
cursor.execute(sql2)   

query = "INSERT INTO table1 (name, class) VALUES('ONE','TWO')" 
cursor.execute(query) 

query2 = "INSERT INTO table2 (name, class,ID) VALUES('SSS','CAR',1)" 
cursor.execute(query2) 

Encore une chose- mettre une virgule (tableau 2) entre FOREIGN KEY (ID) et références donne erreur. ??

edit: Je pense que ma question n'est pas claire. Ce que je veux faire 'ID' dans table2

`ID` integer NOT NULL, 
     FOREIGN KEY (ID) 

référence

`ID` integer NOT NULL AUTO_INCREMENT,  
    PRIMARY KEY (`ID`) 

dans le tableau 1

modifier: LAST_INSERT_ID() fonctionne pour les insertions de ligne unique. MySQL documentation décrit comment utiliser pour plusieurs lignes. Le tableau 2 comporte plusieurs lignes. UPDATE table2 ID SET = LAST_INSERT_ID (ID + 1);

Le message d'erreur que je reçois cette méthode est: Impossible d'ajouter ou mettre à jour une ligne enfant: (. dbtable2, CONTRAINTE table2_ibfk_1 FOREIGN KEY (ID) RÉFÉRENCES table1 (ID)) une contrainte de clé étrangère échoue

+0

@Daniel comment avez-vous fait cela? – Tom

+0

Alors, quelle est votre question? Où avez-vous des erreurs? –

+0

dans la ligne query2 = ..., si je ne mets pas un "1" là, je reçois des erreurs. Je veux référencer l'ID qui s'auto-incruste dans la table1.Donc, je veux savoir ce que je devrais mettre à la place de la 1 afin de faire fonctionner la clé étrangère – Tom

Répondre

1

Dans la requête 2, où vous avez le 1, vous devez insérer l'une des valeurs de ID dans la table1. C'est la signification de FK, pour lancer une erreur si vous n'insérez pas une valeur existant dans la table référencée.

+0

oui, c'est pourquoi j'ai mis un 1 là. Mais comment faire le 1 auto-incrément, comme la variable référencée? – Tom

+0

Lorsque l'autre réponse a été répondue, vous pouvez utiliser LAST_INSERT_ID. Mais vous ne devriez pas le faire autoincrement. Si vous insérez toujours 1 à 1, cela signifie qu'ils sont la même entité et doivent être dans la même table. Si ce n'est pas le cas, vous devez contrôler ce que vous insérez, car vous pouvez insérer un enregistrement dans l'une des tables et aucun dans l'autre. – Luis

0

Question 1) MySQL fournit LAST_INERT_ID(). Pour les opérations sur une seule ligne, cela renvoie le dernier numéro d'auto-incrémentation généré. Pour les insertions à plusieurs lignes, vous devez suivre le nombre de lignes insérées, car LAST_INSERT_ID() renvoie le premier nombre généré pour l'opération.

Voici un à un exemple:

query = "INSERT INTO table1 (name, class) VALUES('ONE','TWO')" 
cursor.execute(query) 

query2 = "INSERT INTO table2 (name, class,ID) VALUES('SSS','CAR',LAST_INSERT_ID())" 
cursor.execute(query2) 

est ici un à plusieurs exemple:

#Insert the parent record 
query = "INSERT INTO table1 (name, class) VALUES('ONE','TWO')" 
cursor.execute(query) 

#get the autoincrement id 
cursor.execute('select LAST_INSERT_ID()') 
parentId = cursor.fetchone()[0] 

#Assuming you have several child records as a list of lists 
childVals = [['SSS','CAR'],['FOO','BAR']] 

#define the template child insert SQL using parameter substitution 
# many dbapi modules use ? as the parameter placeholder, yours may use %s, etc. 
query2 = "INSERT INTO table2 (name, class,ID) VALUES(?,?,?)" 

#insert the child records with the parent id 
for vals in childVals: 
    #pass in the child record values with the parent id 
    cursor.execute(query2, vals + [id]) 

Question 2) Les références se disent FOREIGN KEY où chercher enregistrements connexes, ils font donc partie de la même déclaration et ne doivent pas être séparés par une virgule.

+0

Je ne vois pas comment faire fonctionner les inserts à plusieurs rangées. Je reçois des erreurs de contrainte de clé étrangère – Tom

+0

J'ai ajouté un exemple un-à-plusieurs pour l'insertion de plusieurs enregistrements enfants. Si vous ajoutez plusieurs enregistrements parents, je suggérerais de commencer par les instructions d'insertion parent. Pas le plus efficace, mais c'est simple. – tharen

+0

Si vous avez une instruction d'insertion génère plusieurs lignes ** à la fois ** le curseur indiquera généralement le nombre de lignes affectées, 'cursor.rowcount'. Vous utiliseriez ce rowcount pour incrémenter la réponse LAST_INSERT_ID(). – tharen

Questions connexes