No entanto, estou tentando criar chaves estrangeiras no Laravel quando migro minha tabela usando artisan
o seguinte erro:
[Illuminate\Database\QueryException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL
: alter table `priorities` add constraint priorities_user_id_foreign foreign
key (`user_id`) references `users` (`id`))
Meu código de migração é o seguinte:
arquivo de migração de prioridades
public function up()
{
//
Schema::create('priorities', function($table) {
$table->increments('id', true);
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->string('priority_name');
$table->smallInteger('rank');
$table->text('class');
$table->timestamps('timecreated');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schema::drop('priorities');
}
arquivo de migração de usuários
public function up()
{
//
Schema::table('users', function($table)
{
$table->create();
$table->increments('id');
$table->string('email');
$table->string('first_name');
$table->string('password');
$table->string('email_code');
$table->string('time_created');
$table->string('ip');
$table->string('confirmed');
$table->string('user_role');
$table->string('salt');
$table->string('last_login');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
Schemea::drop('users');
}
Qualquer idéia sobre o que fiz de errado, quero entender agora, pois tenho muitas tabelas que preciso criar, por exemplo: Usuários, Clientes, Projetos, Tarefas, Status, Prioridades, Tipos, Equipes. Idealmente, quero criar tabelas que armazenam esses dados com as chaves estrangeiras, i..e clients_project
e project_tasks
etc.
Espero que alguém possa me ajudar a começar.
Schema::table
método, ajudou! Obrigado!$table->unsignedBigInteger('user_id')
se o seu user.id for #bigIncrements
Pergunta já respondida, mas espero que isso possa ajudar outra pessoa.
Este erro ocorreu para mim porque criei a tabela de migração com a chave estrangeira antes de a chave existir como chave primária na tabela original. As migrações são executadas na ordem em que foram criadas, conforme indicado pelo nome do arquivo gerado após a execução
migrate:make
. Por exemplo2014_05_10_165709_create_student_table.php
.A solução foi renomear o arquivo com a chave estrangeira para um período anterior ao arquivo com a chave primária, conforme recomendado aqui: http://forumsarchive.laravel.io/viewtopic.php?id=10246
Eu acho que também tive que adicionar
$table->engine = 'InnoDB';
fonte
Laravel ^ 5.8
Exemplo
Vamos imaginar que você esteja criando um aplicativo simples baseado em funções e precise fazer referência a user_id na tabela PIVOT "role_user" .
2019_05_05_112458_create_users_table.php
2019_05_05_120634_create_role_user_pivot_table.php
Como você pode ver, a linha comentada gerará uma exceção de consulta, porque, como mencionado nas notas de atualização, as colunas de chave estrangeira devem ser do mesmo tipo ; portanto, você precisa alterar a chave de extração (neste exemplo, é user_id ) para bigInteger na tabela role_user ou altere o método bigIncrements para incrementos na tabela users e use a linha comentada na tabela dinâmica, é com você.
Espero poder esclarecer esta questão para você.
fonte
Schema::table('goal_objective', function (Blueprint $table) { $table->bigInteger('job_title_id')->after('target')->unsigned()->nullable(); $table->foreign('job_title_id')->references('id')->on('job_titles')->onDelete('set null'); }
Funcionou. Obrigado.No meu caso, o problema era que a tabela principal já tinha registros e eu estava forçando a nova coluna a não ser NULL. Então, adicionar um -> nullable () à nova coluna fez o truque. No exemplo da pergunta, seria algo como isto:
$table->integer('user_id')->unsigned()->nullable();
ou:
$table->unsignedInteger('user_id')->nullable();
Espero que isso ajude alguém!
fonte
No meu caso, o problema era que a migração gerada automaticamente para a
users
tabela estava configurandoEntão eu tive que mudar o tipo de coluna
para fazer minha migração com a chave estrangeira funcionar.
Isso com laravel
5.8.2
fonte
No meu caso, o problema era que o tempo de migração tenha cuidado ao criar migrações, primeiro crie a migração filho do que a migração base. Porque se você criar a migração de base primeiro que tiver sua chave estrangeira, procurará tabela filho e não haverá tabela que, em seguida, lança uma exceção.
Além disso:
Quando você cria a migração, ela possui um registro de data e hora no início. digamos que você criou um gato de migração para que ele pareça
2015_08_19_075954_the_cats_time.php
e tenha esse códigoE depois de criar a tabela base, você cria outra raça de migração, a tabela filha, que possui seu próprio horário de criação e data. O código será parecido com:
parece que ambas as tabelas estão corretas, mas quando você executa o php artisan migrate . Isso gerará uma exceção porque a migração criará primeiro a tabela base no seu banco de dados porque você criou essa migração primeiro e nossa tabela base possui restrição de chave estrangeira, que procurará a tabela filho e a tabela filho não existe, o que provavelmente é uma exceção..
Assim:
feito funcionará
fonte
No meu caso, apenas altero a ordem das migrações são executadas manualmente para que os usuários da tabela sejam criados primeiro.
Na pasta database / migrations / seu nome de arquivo de migração, tenha este formato: year_month_day_hhmmss_create_XXXX_table.php
Apenas renomeie o arquivo de usuário de criação para que a data de criação da tabela de prioridades da tabela seja definida depois da data do usuário (até um segundo depois é suficiente)
fonte
No laravel 5.8, a tabela users_ utiliza o
bigIncrements('id')
tipo de dados para a chave primária. Portanto, quando você desejar consultar uma restrição de chave estrangeira, suauser_id
coluna precisará ser dounsignedBigInteger('user_id')
tipo.fonte
Eu estava tendo o mesmo problema usando o Laravel 5.8. Depois de examinar melhor os documentos do laravel, além disso, aqui Migrações e bigIncrements . A maneira como resolvi isso foi adicionando chaves primárias "$ table-> bigIncrements ('id')" a todas as tabelas relacionadas à tabela "users" e suas associações, no meu caso a tabela "role" . Por fim, tive "$ table-> unsignedBigInteger" para associar funções a usuários (muitos-para-muitos), ou seja, tabela "role_user" .
fonte
Eu tive esse problema com o laravel 5.8 e corrigi esse código, como mostrado aqui na documentação do Laravel , para onde quer que eu esteja adicionando uma chave estrangeira.
então eu corri
$ php artisan migrate:refresh
Como essa sintaxe é bastante detalhada, o Laravel fornece métodos adicionais de terser que usam convenção para fornecer uma melhor experiência ao desenvolvedor. O exemplo acima pode ser escrito assim:
fonte
O uso do Laravel 5.3 teve o mesmo problema.
A solução foi usar unsignedInteger em vez de número inteiro ('nome') -> unsigned () .
Então é isso que funcionou
A razão pela qual isso funcionou é o fato de que ao usar número inteiro ('nome') -> não assinado, a coluna criada na tabela tinha comprimento 11, mas ao usar unsigedInteger ('nome'), a coluna tinha comprimento 10.
Comprimento 10 é o comprimento das chaves primárias ao usar o Laravel, de modo que o comprimento das colunas corresponda.
fonte
Esse erro ocorreu para mim porque - enquanto a tabela que eu estava tentando criar era o InnoDB - a tabela estrangeira com a qual eu estava tentando relacioná-la era uma tabela MyISAM!
fonte
Não podemos adicionar relações, a menos que tabelas relacionadas sejam criadas. O Laravel executa migrações ordenadas por data dos arquivos de migração. Portanto, se você deseja criar uma relação com uma tabela que existe no segundo arquivo de migração, ela falha.
Como enfrentei o mesmo problema, criei finalmente mais um arquivo de migração para especificar todas as relações.
fonte
Esteja ciente: quando o Laravel configura uma tabela usando
que é padrão na maioria das migrações, isso configurará um campo inteiro não assinado. Portanto, ao fazer uma referência estrangeira de outra tabela para este campo, verifique se na tabela de referência você define o campo como UnsignedInteger e não (o que eu supunha ser um) campo UnsignedBigInteger.
Por exemplo: no arquivo de migração 2018_12_12_123456_create_users_table.php:
Em seguida, no arquivo de migração 2018_12_12_18000000_create_permissions_table.php, que configura a referência estrangeira novamente para os usuários:
fonte
Você deve escrever desta maneira
O campo de chave estrangeira deve estar sem sinal , espero que ajude !!
fonte
Para fazer adição de restrição de chave estrangeira no laravel, o seguinte funcionou para mim:
Crie a coluna para ser chave estrangeira da seguinte maneira:
Adicionando a linha de restrição imediatamente após (1) ou seja,
fonte
Eu sei que é uma pergunta antiga, mas verifique se você está trabalhando com referências, o mecanismo de suporte adequado está definido. configure o mecanismo innodb para as duas tabelas e o mesmo tipo de dados para as colunas de referência
fonte
Fazendo uma pausa aqui alguns anos após a pergunta original, usando o laravel 5.1, tive o mesmo erro que minhas migrações foram geradas por computador com o mesmo código de data. Passei por todas as soluções propostas e depois refatorado para encontrar a fonte do erro.
Nas laracasts seguintes e na leitura dessas postagens, acredito que a resposta correta é semelhante à resposta de Vickies, com a exceção de que você não precisa adicionar uma chamada de esquema separada. Você não precisa pôr a mesa no Innodb, estou assumindo que o laravel está fazendo isso agora.
As migrações simplesmente precisam ser cronometradas corretamente, o que significa que você modificará o código da data (mais tarde) no nome do arquivo para tabelas nas quais você precisa de chaves estrangeiras. Como alternativa ou além disso, abaixe o código de dados para tabelas que não precisam de chaves estrangeiras.
A vantagem na modificação do código de dados é que seu código de migração será mais fácil de ler e manter.
Até agora, meu código está funcionando, ajustando o código de tempo para atrasar migrações que precisam de chaves estrangeiras.
No entanto, tenho centenas de tabelas, portanto, no final, tenho uma última tabela apenas para chaves estrangeiras. Apenas para fazer as coisas fluírem. Estou assumindo que vou puxá-los para o arquivo correto e modificar o código de dados como eu testá-los.
Por exemplo, um arquivo: file 2016_01_18_999999_create_product_options_table. Este precisa que a tabela de produtos seja criada. Veja os nomes dos arquivos.
a tabela de produtos: isso precisa migrar primeiro. 2015_01_18_000000_create_products_table
E, finalmente, no final do arquivo que estou usando temporariamente para resolver problemas, que refatorarei ao escrever testes para os modelos que chamei 9999_99_99_999999_create_foreign_keys.php. Essas chaves são comentadas quando eu as puxei, mas você entendeu.
fonte
Tão simples !!!
se o seu primeiro
'priorities'
arquivo de migração for criado , o Laravel será executado pela primeira vez'priorities'
enquanto a'users'
tabela não existir.como ele pode adicionar relação a uma tabela que não existe!
Solução: retire os códigos de chave estrangeira da
'priorities'
tabela. seu arquivo de migração deve ser assim:e adicione a um novo arquivo de migração, aqui está o nome
create_prioritiesForeignKey_table
e adicione estes códigos:fonte
certifique-se de que sua coluna de estrangulamento esteja com muita raiva da coluna-chave de estrangulamento
Quero dizer que sua chave externa (na segunda tabela) deve ser o mesmo tipo da sua chave principal do ponter (na primeira tabela)
sua chave principal do ponteiro deve ser um método não assinado, deixe-me mostrar:
na sua PRIMEIRA tabela de migração:
na sua SEGUNDA tabela de migração:
OUTRO EXEMPLO PARA VER DIFERENÇA
na sua PRIMEIRA tabela de migração:
na sua SEGUNDA tabela de migração:
VER INTERVALOS DE TABELA DE TIPOS NUMÉRICOS MYSQL
fonte
Uma coisa que notei é que, se as tabelas usarem um mecanismo diferente da restrição de chave estrangeira, não funcionará.
Por exemplo, se uma tabela usar:
E os outros usos
geraria um erro:
Você pode corrigir isso adicionando o InnoDB no final da criação da tabela da seguinte maneira:
fonte
No meu caso, eu estava referenciando uma coluna inteira
id
em uma coluna de stringuser_id
. Eu mudei:$table->string('user_id')
para:
$table->integer('user_id')->unsigned();
Espero que ajude alguém!
fonte
A essência é que o método estrangeiro usa
ALTER_TABLE
para transformar um campo preexistente em uma chave estrangeira. Então você precisa definir o tipo de tabela antes de aplicar a chave estrangeira. No entanto, ele não precisa estar em umaSchema::
chamada separada . Você pode fazer as duas coisas no create, assim:Observe também que o tipo de
user_id
está definido como não assinado para corresponder à chave estrangeira.fonte
Você pode passar diretamente o parâmetro booleano na coluna número inteiro dizendo que ele deve estar sem sinal ou não. No laravel 5.4, o código a seguir resolveu meu problema.
Aqui, o segundo parâmetro false representa que não deve ser incrementado automaticamente e o terceiro parâmetro true representa que não deve ser assinado. Você pode manter a restrição de chave estrangeira na mesma migração ou separá-la. Funciona em ambos.
fonte
Se nenhuma das soluções acima funcionar para iniciantes, verifique se os dois IDs têm o mesmo tipo: ambos são
integer
ou ambos sãobigInteger
, ... Você pode ter algo parecido com isto:Tabela principal (usuários por exemplo)
Tabela filho (prioridades por exemplo)
Essa consulta falhou porque
users.id
é umBIG INTEGER
considerando quepriorities.user_id
é umINTEGER
.A consulta correta nesse caso seria a seguinte:
fonte
No meu caso, não funcionou até eu executar o comando
Dessa forma, você pode deixar as chaves estrangeiras dentro do esquema de criação
fonte
Também pode ser a ordem de migração da criação. Se você primeiro criar a tabela de prioridades e depois da tabela de usuários, ela estará errada. Por causa da primeira migração, procurando a tabela de usuários. Então, você deve alterar a ordem da migração em
diretório
fonte
Para mim, a coluna da tabela que minha tabela filha referenciou não foi indexada.
Ignore o nome terrível, é de outro sistema terrivelmente projetado.
fonte
Às vezes, esse erro pode ocorrer devido à sequência de migrações.
Like Users e Order são duas tabelas
A tabela de pedidos possui a chave estrangeira dos usuários (durante a migração, se a tabela de pedidos migrar primeiro, isso causará o problema porque não há usuários que correspondam à chave estrangeira)
Solução: basta colocar a tabela Atualização de pedidos sob os usuários para atualização
Exemplo: No meu caso, tabelas Educação e Universidade Tabela Educação
Na Universidade
fonte
Uma coisa que acho que falta nas respostas aqui e me corrija se estiver errado, mas as chaves estrangeiras precisam ser indexadas na tabela dinâmica. Pelo menos no mysql, esse parece ser o caso.
fonte