Naruszenie ograniczenia integralności: 1452 Nie można dodać ani zaktualizować wiersza podrzędnego:

84

Próbuję wstawić wartości do mojej tabeli komentarzy i pojawia się błąd. Mówi, że nie mogę dodawać ani aktualizować wiersza podrzędnego i nie mam pojęcia, co to oznacza.

mój schemat wygląda mniej więcej tak

-- ----------------------------
-- Table structure for `comments`
-- ----------------------------
DROP TABLE IF EXISTS `comments`;
CREATE TABLE `comments` (
  `id` varchar(36) NOT NULL,
  `project_id` varchar(36) NOT NULL,
  `user_id` varchar(36) NOT NULL,
  `task_id` varchar(36) NOT NULL,
  `data_type_id` varchar(36) NOT NULL,
  `data_path` varchar(255) DEFAULT NULL,
  `message` longtext,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_comments_users` (`user_id`),
  KEY `fk_comments_projects1` (`project_id`),
  KEY `fk_comments_data_types1` (`data_type_id`),
  CONSTRAINT `fk_comments_data_types1` FOREIGN KEY (`data_type_id`) REFERENCES `data_types` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_comments_projects1` FOREIGN KEY (`project_id`) REFERENCES `projects` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_comments_users` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf32;

-- ----------------------------
-- Records of comments
-- ----------------------------

-- ----------------------------
-- Table structure for `projects`
-- ----------------------------
DROP TABLE IF EXISTS `projects`;
CREATE TABLE `projects` (
  `id` varchar(36) NOT NULL,
  `user_id` varchar(36) NOT NULL,
  `title` varchar(45) DEFAULT NULL,
  `description` longtext,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_projects_users1` (`user_id`),
  CONSTRAINT `fk_projects_users1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf32;

-- ----------------------------
-- Records of projects
-- ----------------------------
INSERT INTO `projects` VALUES ('50dcbc72-3410-4596-8b71-0e80ae7aaee3', '50dcbc5c-d684-40bf-9715-0becae7aaee3', 'Brand New Project', 'This is a brand new project', '2012-12-27 15:24:02', '2012-12-27 15:24:02');

a instrukcja mysql, którą próbuję zrobić, wygląda mniej więcej tak

INSERT INTO `anthonyl_fbpj`.`comments` (`project_id`, `user_id`, `task_id`, `data_type_id`, `message`, `modified`, `created`, `id`) 
VALUES ('50dc845a-83e4-4db3-8705-5432ae7aaee3', '50dcbc5c-d684-40bf-9715-0becae7aaee3', '1', '50d32e5c-abdc-491a-a0ef-25d84e9f49a8', 'this is a test', '2012-12-27 19:20:46', '2012-12-27 19:20:46', '50dcf3ee-8bf4-4685-aa45-4eb4ae7aaee3')

otrzymany błąd wygląda następująco

SQLSTATE [23000]: Naruszenie ograniczenia integralności: 1452 Nie można dodać lub zaktualizować wiersza podrzędnego: ograniczenie klucza obcego nie powiodło się ( anthonyl_fbpj. comments, OGRANICZANIE fk_comments_projects1 KLUCZA OBCEGO ( project_id) REFERENCJE projects( id) ON DELETE BRAK AKCJI PRZY AKTUALIZACJI BRAK AKCJI)

numeryczne25
źródło

Odpowiedzi:

124

Oznacza to po prostu, że wartość kolumny project_idw tabeli, commentsktórą wstawiasz, nie istnieje w tabeli projects. Należy pamiętać, że wartości kolumny project_idw tabeli commentszależą od wartości IDw tabeli Projects.

Wartość 50dc845a-83e4-4db3-8705-5432ae7aaee3wstawiana dla kolumny project_idnie istnieje w tabeli projects.

John Woo
źródło
26
Co jeśli mam wartość w tej tabeli? Mam ten sam błąd, ale wartości w tabeli i ID są zgodne.
Sergey Romanov
4
Miałem podobny problem. Usunięcie starych danych z tabeli rozwiązało problem w moim przypadku.
Yojan,
3
Yojan, którą tabelę powinniśmy usunąć, „nadrzędną” czy „podrzędną” (zależną)?
Fistaszki
46

Upewnij się, że masz project_idw fillableposiadaniu swojego Commentmodelu.

Miałem ten sam problem i to był powód.

Jyothu
źródło
8
To samo tutaj, używając Laravel. Dobry chwyt.
PapaHotelPapa
8

Upewnij się również, że dodany klucz obcy jest tego samego typu, co oryginalna kolumna, jeśli kolumna, do której się odwołujesz, nie jest tego samego typu, również zakończy się niepowodzeniem.


źródło
5

Jeśli dodajesz nowy klucz obcy do istniejącej tabeli, a kolumny nie są puste i nie mają przypisanej wartości domyślnej, otrzymasz ten błąd,

Albo trzeba to zrobić nullablealbo assign default value, lub delete all the existing records, aby go rozwiązać.

Prafulla Kumar Sahu
źródło
5

Oznacza to, że wartość kolumny project_idw tabeli, commentsktórą wstawiasz, nie tylko doesn't existw projektach tabeli, aleproject_id prawdopodobnie również nie ma wartości domyślnej . Np. W moim przypadku ustawiłem ją na NULL.

Jeśli chodzi o Laravel, możesz potraktować to wyrażenie jako fragment kodu migracyjnego pliku php, na przykład:

class ForeinToPhotosFromUsers extends Migration

{ /** * Run the migrations. * * @return void */

public function up()
{
    Schema::table('users', function (Blueprint $table) {
    $table->unsignedBigInteger('photo_id')->nullable();// ! ! ! THIS STRING ! ! !
    $table->foreign('photo_id')->references('id')->on('photos');
});
}

}

Oczywiście obok tego wszystkiego trzeba było stworzyć klasę Model (w moim przypadku była to Photo).

CodeToLife
źródło
4

Najpierw usuń ograniczenie „fk_comments_projects1”, a także jego indeks. Następnie odtwórz go.

Sreerag AS
źródło
4

Mam nadzieję, że moja decyzja pomoże. Miałem podobny błąd w Laravel. Dodałem klucz obcy do złej tabeli.
Niepoprawny kod:

Schema::create('comments', function (Blueprint $table) {
$table->unsignedBigInteger('post_id')->index()->nullable();
...
$table->foreign('post_id')->references('id')->on('comments')->onDelete('cascade');
    });


Schema::create('posts', function (Blueprint $table) {
    $table->bigIncrements('id');
    ...
    });

Zwróć uwagę na funkcję w („komentarze”) powyżej. Prawidłowy kod

 $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
Aleksergio
źródło
3

Ten błąd pojawia się również, jeśli nie utworzysz i nie wypełnisz swoich tabel we właściwej kolejności. Na przykład, w zależności od schematu, Komentarze potrzeb stołowe user_id, project_id, task_idi data_type_id. Oznacza to, że Usersstół, Projectsstół, Taskstół i Data_Typestół muszą już wyjść i zawierać wartości, zanim będzie można odwołać się do ich identyfikatorów lub jakiejkolwiek innej kolumny.

W Laravel oznaczałoby to wywołanie seederów bazy danych w odpowiedniej kolejności:

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UserSeeder::class);
        $this->call(ProjectSeeder::class);
        $this->call(TaskSeeder::class);
        $this->call(DataTypeSeeder::class);
        $this->call(CommentSeeder::class);
    }
}

W ten sposób rozwiązałem podobny problem.

KC Samm
źródło
2

Jeśli ktoś używa Laravel i napotyka ten problem. Otrzymywałem to również i problem był w kolejności, w której wstawiałem identyfikatory (tj. Klucze obce) do tabeli przestawnej.

Aby być konkretnym, poniżej przykład relacji wiele do wielu:

wordtokens <-> wordtoken_wordchunk <-> wordchunks

// wordtoken_wordchunk table
Schema::create('wordtoken_wordchunk', function(Blueprint $table) {
        $table->integer('wordtoken_id')->unsigned();
        $table->integer('wordchunk_id')->unsigned();

        $table->foreign('wordtoken_id')->references('id')->on('word_tokens')->onDelete('cascade');
        $table->foreign('wordchunk_id')->references('id')->on('wordchunks')->onDelete('cascade');

        $table->primary(['wordtoken_id', 'wordchunk_id']);
    });

// wordchunks table
Schema::create('wordchunks', function (Blueprint $table) {
        $table->increments('id');
        $table->timestamps();
        $table->string('text');
    });

// wordtokens table
Schema::create('word_tokens', function (Blueprint $table) {
        $table->increments('id');
        $table->string('text');
});

Teraz moje modele wyglądają następująco:

class WordToken extends Model
{
   public function wordchunks() {
      return $this->belongsToMany('App\Wordchunk');
   }
}

class Wordchunk extends Model
{

    public function wordTokens() {
        return $this->belongsToMany('App\WordToken', 'wordtoken_wordchunk', 'wordchunk_id', 'wordtoken_id');
    }
}

Rozwiązałem problem, zmieniając kolejność „wordchunk_id” i „wordtoken_id” w modelu Wordchunk.

Aby uzupełnić kod, utrwalam modele w następujący sposób:

private function persistChunks($chunks) {
    foreach ($chunks as $chunk) {
        $model = new Wordchunk();
        $model->text = implode(' ', array_map(function($token) {return $token->text;}, $chunk));
        $tokenIds = array_map(function($token) {return $token->id;}, $chunk);
        $model->save();
        $model->wordTokens()->attach($tokenIds);
    }
}
narko
źródło
2

Może masz jakieś wiersze w tabeli, które chcesz utworzyć de FK.

Uruchom migrację z wartością Foreign_key_checks OFF Wstaw tylko te rekordy, które mają odpowiednie pole id w spisie treści.

Antonio Figueiredo Tamura
źródło
1

Miałem ten problem, gdy przypadkowo użyłem NIEPRAWIDŁOWEGO „uuidu” w rekordzie dziecka. Kiedy tak się dzieje, ograniczenie patrzy od dziecka do rekordu nadrzędnego, aby upewnić się, że łącze jest poprawne. Generowałem go ręcznie, kiedy już skonfigurowałem mój Model, aby robił to automatycznie. Więc moja poprawka brzmiała:

$parent = Parent:create($recData); // asssigning autogenerated uuid into $parent

Następnie, kiedy zadzwoniłem do mojej klasy podrzędnej, aby wstawić dzieci, przekazałem tę wartość zmiennej:

$parent->uuid

Mam nadzieję, że to pomoże.

Mark Löwe
źródło
0

Miałem ten sam błąd, problem polegał na tym, że próbowałem dodać role_idobcy do userstabeli, ale role_idnie miałem wartości domyślnej, więc DB nie pozwolił mi wstawić kolumny, ponieważ miałem już kilku użytkowników i nie było wiedzieć, jak dodać do nich kolumnę. Ponieważ byłem w fazie rozwoju, właśnie użyłem migrate:fresh, ale gdybym był na produkcji, prawdopodobnie ustawiłbym domyślną wartość na role_idi nie ograniczałbym jej, dopóki nie otrzymałem odpowiedniej roli w DB.

Artur Junior
źródło