I've had to change a table in my database so that the primary key isn't the standard increments.
Here's the migration,
public function up()
{
Schema::create('settings', function (Blueprint $table) {
$table->text('code', 30)->primary();
$table->timestamps();
$table->text('name');
$table->text('comment');
});
}
However, MySQL keeps returning with,
Syntax error or access violation: 1170 BLOB/TEXT column 'code' used in
key specification without a key length (SQL: alter table settings
add primary key settings_code_primary(code)
I've tried leaving the normal increments id in there and modifying the table in a different migration but the same thing happens.
Any ideas of what I'm doing wrong?
Laveral Version 5.4.23
Change it to string.
$table->string('code', 30)->primary();
Related
My laravel migration is like below
public function up()
{
Schema::create('account_main', function (Blueprint $table) {
$table->increments('user_sn')->primary();
$table->string('member_username', 20);
$table->string('login_password', 255);
$table->integer('login_count')->default('0')->unsigned();
});
}
When I ran "php artisan migrate", show error "1068 Multiple primary key".
Could someone help to find the problem.
You don't need the ->primary() because already ->increments('...') includes it.
It's like if in MySQL you write this:
PK INT AUTO_INCREMENT PRIMARY KEY;
PRIMARY KEY(PK)
You are declaring two times the same primary key
In Laravel Eloquent ORM the type increments will be defined as primary key automatically. So don't need to use primary() method.
If the column is integer.
$table->increments('user_sn');
If the column is string
$table->string('user_sn')->primary();
If you want any other column to be unique (instead of primary key)
$table->increments('user_sn');
$table->string('member_username', 20)->unique(); // cannot contain duplicate values
I'm trying to figure out how migrations in Laravel work. Here you can see I'm creating 2 tables. And in the second table (RealNationalLeague), I'm having foreign keys to two columns (real_nation_id, level) in the first table (RealNationalLeagueLevel).
public function up()
{
...
Schema::create(Model\RealNationalLeagueLevel::TABLE, function (Blueprint $table) {
$table->unsignedInteger("real_nation_id");
$table->unsignedTinyInteger("level");
$table->foreign("real_nation_id")->references("id")->on(Model\RealNation::TABLE);
$table->primary(["real_nation_id", "level"]);
});
Schema::create(Model\RealNationalLeague::TABLE, function (Blueprint $table) {
$table->increments("id");
$table->unsignedInteger("real_nation_id");
$table->unsignedTinyInteger("level");
$table->string("name", 32);
$table->foreign("real_nation_id")->references("real_nation_id")->on(Model\RealNationalLeagueLevel::TABLE); // this works
$table->foreign("level")->references("level")->on(Model\RealNationalLeagueLevel::TABLE); // this does not
});
}
Running the migration does not work. It throws QueryException:
SQLSTATE[HY000]: General error: 1005 Can't create table `testdb`.`#sql-17a00_448a37` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `real_national_league` add constraint `real_national_league_level_foreign` foreign key (`level`) references `real_national_league_level` (`level`))
Any idea why it's not working? Thanks for any help.
The table that you want to reference, you have to create it first, then in another migration, create a column from this table to that reference table.
I am using Laravel 5.2 ,there is an error when I run php artisan migrate,as follows:
2016_06_12_134655_create_categories_table.php
public function up() {
Schema::create('categories', function(Blueprint $table) {
$table->increments('id');
$table->string('category');
$table->timestamps();
});
}
2016_06_12_134659_create_goods_table.php
public function up() {
Schema::create('goods', function(Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('unit_price');
$table->integer('user_id')->unsigned();
$table->tinyInteger('category_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('category_id')->references('id')->on('categories');
$table->timestamps();
});
}
$php artisan migrate
what should I do?
It might be complaining about your use of tinyInteger on category_id, try setting it to integer as well - assuming your categories table exists. If it does not, you need to make sure any migrations with a foreign key constraint have their related tables migrated before them. Without seeing your categories table, I might wonder whether the datatype for your id is the same as well.
The referenced table categories has a primary key of type int. Keep the same in the referencing column category_id if You want to keep foreign key constraints, defined in line:
$table->foreign('category_id')->references('id')->on('categories');
When you use primary key $table->Increments('id');
you should use Integer as a foreign key
$table-> unsignedInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->tinyIncrements('id');
you should use unsignedTinyInteger as a foreign key
$table-> unsignedTinyInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->smallIncrements('id');
you should use unsignedSmallInteger as a foreign key
$table-> unsignedSmallInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->mediumIncrements('id');
you should use unsignedMediumInteger as a foreign key
$table-> unsignedMediumInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
I have migrations as follows:
create_users_table.php
class CreateUsersTable extends Migration {
public function up()
{
Schema::create('users', function(Blueprint $table) {
$table->increments('id');
$table->string('name', 255);
$table->string('username', 64)->unique();
$table->string('email', 255)->unique();
$table->string('password',64);
$table->timestamps();
});
}
public function down()
{
Schema::drop('users');
}
}
create_predictions_table.php
class CreatePredictionsTable extends Migration {
public function up()
{
Schema::create('predictions', function(Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->integer('fixture_id')->unsigned();
$table->foreign('fixture_id')->references('id')->on('fixtures');
$table->integer('home_team_score_prediction');
$table->integer('away_team_score_prediction');
$table->timestamps();
});
}
public function down()
{
Schema::drop('predictions');
}
}
create_fixtures_table.php
class CreateFixturesTable extends Migration {
public function up()
{
Schema::create('fixtures', function(Blueprint $table) {
$table->increments('id');
$table->integer('home_team_id');
$table->integer('away_team_id');
$table->dateTime('date');
$table->string('venue');
$table->timestamps();
});
}
public function down()
{
Schema::drop('fixtures');
}
}
Initially when I ran the migration using
php artisan migrate
I hadn't added foreign key's. I ran
php artisan migrate:refresh
after adding the foreign key constraints which gave me following errror:
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'predictions' already exists (SQL: create table `predictions` (`id` int unsigned not null auto_increment primary key, `user_id` int unsigned not null, `fixture_id` int
unsigned not null, `home_team_score_prediction` int not null, `away_team_score_prediction` int not null, `created_ at` timestamp default 0 not null, `updated_at` timestamp default 0 not null) default character set utf8 collate utf8_unicode_ci)
I think that is because the table was already there (although refresh is supposed to rollback the migrations and run them again)
When I tried to rollback using
php artisan migrate:rollback
I got the following:
[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1217 Cannot delete or update a parent row: a foreign key constrain t fails (SQL: drop table `users`)
Where am I going wrong? I'm new to migrations, so these might be errors beginners usually get. But I don't understand what exactly I'm doing wrong. I hope someone can help me out here.
migration will continue until it meets some problem. So probably a foreign key has already been added, but its associated table is not created yet due to error. If you are trying to rollback, migration will assume that the table associated with a foreign key exists and it will try to rollback that table too.
However, that table does not exist!
Well, the simplest way is to empty the database and rerun migration. I met this problem before and find it hard to rollback step by step once such a problem occurs.
What I Did
There is a migrations table for Laravel.
Truncate or empty the table, then delete all tables related to your migrations.
If possible remove any constraints to the foreign keys first before deleting the table.
You should be good to go migrating again.
Addition
Take care of the order of deletion of tables in down() function.
Deleting some tables with referential constraints as declared by onDelete() definitely needs constraints to be removed first.
I think that's causing your rollback error.
Look more into your migrations , buddy :-)
Why do I have a problem creating a table using Laravel Migrations Schema Builder?
The problem occurs with a table with a self-referencing foreign key.
Schema::create('cb_category', function($table)
{
$table->integer('id')->primary()->unique()->unsigned();
$table->integer('domain_id')->unsigned();
$table->foreign('domain_id')->references('id')->on('cb_domain');
$table->integer('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
$table->string('name');
$table->integer('level');
});
SQLSTATE[HY000]: General error: 1005 Can't create table 'eklik2.#sql-7d4_e' (errno: 150) (SQL: alter table `cb_category` add constraint cb_category_parent_id_foreign foreign key (`parent_id`) references `cb_category` (`id`) on delete cascade on update cascade) (Bindings: array ())
[PDOException]
SQLSTATE[HY000]: General error: 1005 Can't create table 'eklik2.#sql-7d4_e' (errno: 150)
You have to break this into two Schema blocks, one creating the columns, the other adding the FKs. mysql can't do both at the same time.
Two querys work :
Schema::create('cb_category', function($table)
{
$table->integer('id')->primary()->unique()->unsigned();
$table->integer('parent_id')->nullable();
});
Schema::table('cb_category', function (Blueprint $table)
{
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
});
I may be too late for the party, but the official docs claim that the foreign key, in case of integer, must be ->unsigned();
http://laravel.com/docs/4.2/schema#foreign-keys
Note: When creating a foreign key that references an incrementing
integer, remember to always make the foreign key column unsigned.
Also, Artisan does not fail if you (as I have) misspell unsigned() and I have spent quite a few hours trying to figure out why the key was not created.
So two things:
1. Always make the foreign key column unsigned in case of incrementing integers
2. Check the spelling of unsigned()
Also a late response but probably a more idiomatic way for Laravel 8:
use App\Models\CbCategory;
...
Schema::create("cb_category", function(Blueprint $table)
{
$table->id();
$table->foreignIdFor(CbCategory::class, "parent_id")
->constrained()
->cascadeOnUpdate()
->cascadeOnDelete()
->nullable();
});
Please Note: I guessed the class name of CbCategory here. Using the class reference firsthand (instead of the former table name string) enables your static code checkers to pick up on future class name changes.
Also the _id-suffix at the parent_id column name is important.
May the following resources quench your thirst for knowledge:
id(): https://laravel.com/docs/8.x/migrations#column-method-id
foreignIdFor(): https://laravel.com/api/8.x/Illuminate/Database/Schema/Blueprint.html
cascadeOnDelete() & cascadeOnUpdate(): https://laravel.com/api/8.x/Illuminate/Database/Schema/ForeignKeyDefinition.html
Schema::create('cb_category', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('domain_id')->unsigned();
$table->foreign('domain_id')->references('id')->on('cb_domain');
$table->integer('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
$table->string('name');
$table->integer('level');
});
Try this
I think you have another table that references the current table that you want to create.
I had this problem and remove that table and my problem was solved
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->integer('parent_id')->unsigned();
$table->foreign('parent_id')->on('categories')->references('id');
});
i got same error when i used this code, after change "$table->integer('parent_id')->unsigned()" to "$table->bigInteger('parent_id');"
my problem solved.
The point here is to make sure that the type of foreign key is the same as the primary key.
Since Laravel 8+ you don't have to break into two Schema blocks. You can use
foreignIdFor(CbCategory::class, 'cb_category_id') and it will create a column named cb_category_id
Ex.
Schema::create("cb_category", function(Blueprint $table)
{
$table->id();
$table->foreignIdFor(CbCategory::class, 'cb_category_id')->nullable()->constrained()->cascadeOnUpdate()->cascadeOnDelete();
});
Any additional column modifiers (Ex. nulleable) must be called before the constrained method.
You can use a second parameter in foreignIdFor for the referencing column name (in case it isn't 'id') NOT for the name you want it to have, in your case the name will automatically be 'cb_category_id'