How to implement partition in laravel database migration - laravel

Using Laravel 5.3 how can I implement partition. Following is the mysql table structure I'm trying to add in migration.
CREATE TABLE `settings` (
`id` INT(10) unsigned NOT NULL AUTO_INCREMENT,
`client_id` INT(11) NOT NULL,
`key` VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL,
`value` TEXT COLLATE utf8_unicode_ci NOT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY `settings_id_primary` (`client_id`, `id`),
UNIQUE KEY `settings_key_unique` (`client_id`, `key`),
KEY `settings_id_key` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci PARTITION BY KEY (`client_id`) PARTITIONS 50;
Below is what I tried so far, but this is only adding columns & keys.
Schema::create('settings', function(Blueprint $table) {
$table->integer('id'); // I can't use increments, because throwing an error when I try to add primary key below
$table->integer('client_id');
$table->string('key');
$table->text('value');
$table->timestamps();
$table->primary(['client_id', 'id']);
$table->unique(['client_id', 'key']);
});
How can I do the partition? If there migration doesn't support partition. Is there way I can dump the whole SQL query in the migration and run.

I think it is help to you,
Schema::create('settings', function(Blueprint $table) {
$table-> increments('id');
$table->integer('client_id')->primary();
$table->string('key');
$table->text('value');
$table->timestamps();
$table->unique(['client_id', 'key']);
});
or
Schema::create('settings', function(Blueprint $table) {
$table-> increments('id');
$table->integer('client_id');
$table->string('key');
$table->text('value');
$table->timestamps();
$table->primary('client_id');
$table->unique(['client_id', 'key']);
});
I searched everywhere, i can't solution find for partition.
But,
My suggestion use, below unprepared into the migration file functions of up and down function
DB::unprepared()
in migration to run your SQL query with partition.
like,
DB::unprepared('create table....')

There's now a Composer package for this called brokenice/laravel-mysql-partition:
https://packagist.org/packages/brokenice
Here's a sample right from the docs:
// You use their extended Schema class:
use Brokenice\LaravelMysqlPartition\Schema\Schema;
// You might also need this (I didn't need it for partitioning by hash):
use Brokenice\LaravelMysqlPartition\Models\Partition;
// I omitted class and method definition boilerplate...
// Create a table as you would normally:
Schema::create('partitioned', static function (Blueprint $table) {
// ...
});
// Now partition it (it will run an ALTER TABLE query):
Schema::partitionByList(
'partitioned',
'id',
[
new Partition('server_east', Partition::LIST_TYPE, [1,43,65,12,56,73]),
new Partition('server_west', Partition::LIST_TYPE, [534,6422,196,956,22])
]
);

Related

Laravel Polymorphic Relationship - Many to Many issue

Have students, that can have documents.
Documents can either be 'just documents' that belong to students (normal one to many relationship)
However, Students can also have 'passports' and 'visas' (amongst others). Each passport and visa can have a document too. A single document can belong to many things (eg, one document can be associated with a passport and a visa). For the purpose of this troubleshooting, lets keep it simple and between Student / Passport (I've also left out other class stuff like fillable just to keep this brief).
Student Model:
class Student extends Model
{
public function documents() {
return $this->hasMany('App\StudentDocument');
}
public function visas() {
return $this->hasMany('App\StudentVisa');
}
public function passports() {
return $this->hasMany('App\StudentPassport');
}
}
Student Passport Class
class StudentPassport extends Model
{
public function student_documents()
{
return $this->morphToMany(StudentDocument::class, 'student_documentable');
}
}
Student Passport Store:
public function store(StudentPassportRequest $request, $student_id)
{
$student = Student::findOrFail($student_id);
$passport = $student->passports()->create($request->all());
if ($request->file('student_document_file')->isValid()) {
$uploaded_file = $request->file('student_document_file');
$filename = time().'-'.$uploaded_file->getClientOriginalName();
Storage::disk('local')->putFileAs(
'student_document_files/'. \Auth::user()->userable_id .'/'. $student_id .'/',
$uploaded_file,
$filename
);
$student_document = new StudentDocument;
$student_document->filename = $filename;
$student_document->student_document_type_id = StudentDocumentType::where('student_document_type','Passport')->first()->id;
$student_document->original_filename = $uploaded_file->getClientOriginalName();
$student_document->mime = $uploaded_file->getMimeType();
$student_document->student_id=$student_id;
$passport->student_documents()->save($student_document);
}
return redirect('/baadmin/students/'. $student_id .'#kt_tabs-passports')->with('flash_message', ['success','Created Successfully','Student Passport "'. $request->input('passport_number') .'" created successfully!']);
}
Error:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'student_documentables' doesn't exist
INSERT INTO `student_documentables` (
`student_document_id`,
`student_documentable_id`,
`student_documentable_type`
)
VALUES
(5, 503, App \ StudentPassport)
I took the example as found in the Laravel Documentation here and just renamed 'tag' to student_documents' essentially. The student_documentable table doesnt exist of course, as it should be plugging it into the student_documents table.
Schema:
CREATE TABLE `student_documents` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`student_id` bigint(20) unsigned NOT NULL,
`student_document_type_id` bigint(20) unsigned NOT NULL,
`filename` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`mime` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`original_filename` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`primary_date` datetime NOT NULL DEFAULT current_timestamp(),
`secondary_date` datetime DEFAULT NULL,
`student_documentable_id` bigint(20) DEFAULT NULL,
`student_documentable_type` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `student_id_index` (`student_id`),
KEY `student_document_type_id_index` (`student_document_type_id`),
KEY `student_documentable_id_index` (`student_documentable_id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
What am I doing wrong or is Laravel just not understanding 'student_documents'?
I can of course change the Student Passport Class to not plug into 'student_documentable' and use 'student_document' then it would try put in the data to the correct table, but I dont know if this is right since all documentation refers to adding an 'able' at the end...
You should first create a pivot table for that MorphMany relation,
Schema::create('student_documentables', function (Blueprint $table)
{
// optional depends if you want an id or not
$table->id();
// here singular is used, to generate student_documentable_type and student_documentable_id fields
$table->morphs('student_documentable');
// the foreign key to student_document
$table->unsignedInteger('student_document_id');
$table->foreign('student_document_id')->on('student_documents')->references('id')->onUpdate('cascade')->onDelete('cascade');
});
In your StudentDocument :
// we define a relation to retrieve all documentables like passport that are linked to that document
public function student_documentables()
{
return $this->morphTo('student_documentables');
}
In your StudentPassport :
// we define a relation to retrieve all documents linked to that passport
public function student_documents()
{
return $this->morphMany(StudentDocument::class, 'student_documentables');
}

General error: 1215 Cannot add foreign key constraint default character set utf8mb4 collate 'utf8mb4_unicode_ci'

I don't understand why I am receiving this error because I don't use reference in users table. The following migration is for user table:
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('password');
$table->string('email')->unique();
$table->integer('hostname_id')->default(0)->unsigned();
$table->integer('main_role_id')->default(2)->unsigned();
$table->bigInteger('phone')->default('+37360000000');
$table->string('job_title');
$table->integer('photo_id')->unsigned()->nullable()->index()->default(1);
$table->date('birth_date');
$table->boolean('enabled')->default(true);
$table->integer('points')->default(0);
$table->integer('experience')->default(0);
$table->timestamps();
});
and I am receiving this error :
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: create table users (id bigint unsigned not null auto_increment primary key, name varchar(191) not null, password varchar(191) not null, email varchar(191) not null, hostname_id int unsigned not null default '0', main_role_id int unsigned not null default '2', phone bigint not null default '+37360000000', job_title varchar(191) not null, photo_id int unsigned null default '1', birth_date date not null, enabled tinyint(1) not null default '1', points int not null default '0', experience int not null default '0', created_at timestamp null, updated_at timestamp null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')

How to create laravel migration for tables with multiple foreign keys?

I want to create a table with multiple foreign keys. Here is the sql:
CREATE TABLE `customers` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`address` varchar(100) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`type_id` tinyint(3) unsigned DEFAULT NULL,
`district_id` tinyint(3) unsigned DEFAULT NULL,
`city_id` tinyint(3) unsigned DEFAULT NULL,
`business_id` tinyint(3) unsigned DEFAULT NULL,
`group_id` tinyint(3) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_customer_1` (`district_id`,`city_id`),
KEY `FK_customer_2` (`business_id`),
KEY `FK_customer_3` (`group_id`),
KEY `FK_customer_4` (`type_id`),
CONSTRAINT `FK_customer_1` FOREIGN KEY (`district_id`, `city_id`)
REFERENCES `cities` (`district_id`, `city_id`) ON DELETE CASCADE,
CONSTRAINT `FK_customer_2` FOREIGN KEY (`business_id`) REFERENCES `businesses` (`business_id`) ON DELETE CASCADE,
CONSTRAINT `FK_customer_3` FOREIGN KEY (`group_id`) REFERENCES `groups` (`group_id`) ON DELETE CASCADE,
CONSTRAINT `FK_customer_4` FOREIGN KEY (`type_id`) REFERENCES `types` (`type_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
I wrote a migration file with the following:
Schema::create('customers', function (Blueprint $table) {
$table->increments('id');
$table->string('name',50);
$table->string('address',100)->nullable();
$table->string('email',50)->nullable();
$table->integer('type_id')->unsigned()->index();
$table->integer('district_id')->unsigned()->index();
$table->integer('city_id')->unsigned()->index();
$table->integer('business_id')->unsigned()->index();
$table->integer('group_id')->unsigned()->index();
$table->timestamps();
$table->foreign(['district_id','city_id'])->references(['district_id','city_id'])->on('cities')->onDelete('cascade');
$table->foreign('business_id')->references('business_id')->on('businesses')->onDelete('cascade');
$table->foreign('type_id')->references('type_id')->on('types')->onDelete('cascade');
$table->foreign('group_id')->references('group_id')->on('groups')->onDelete('cascade');
});
But when I run the migration it gives me the following error.
SQLSTATE[HY000]: General error: 1005 Can't create table `wastewater`.`#sql-5a8_18a` (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table `customers` add constraint `customers_district_id_city_id_foreign` foreign key (`district_id`, `city_id`) references `cities` (`district_id`, `city_id`) on delete cascade)`
How can I this?
Can you please Try this way, Just removed array and define with comma-separated only.
Schema::create('customers', function (Blueprint $table) {
$table->increments('id');
$table->string('name',50);
$table->string('address',100)->nullable();
$table->string('email',50)->nullable();
$table->integer('type_id')->unsigned()->index();
$table->integer('district_id')->unsigned()->index();
$table->integer('city_id')->unsigned()->index();
$table->integer('business_id')->unsigned()->index();
$table->integer('group_id')->unsigned()->index();
$table->timestamps();
$table->foreign('district_id','city_id')->references('district_id','city_id')->on('cities','cities')->onDelete('cascade','cascade');
$table->foreign('business_id')->references('business_id')->on('businesses')->onDelete('cascade');
$table->foreign('type_id')->references('type_id')->on('types')->onDelete('cascade');
$table->foreign('group_id')->references('group_id')->on('groups')->onDelete('cascade');
});
Try the following way, it will work.
Schema::create('customers', function (Blueprint $table) {
$table->increments('id');
$table->integer('type_id', false, true);
$table->foreign('type_id')->references('type_id')->on('types')
->onDelete('cascade');
$table->integer('district_id', false, true);
$table->foreign('district_id')
->references('district_id')->on('cities')
->onDelete('cascade');
$table->integer('city_id', false, true);
$table->foreign('city_id')
->references('city_id')->on('cities')
->onDelete('cascade');
$table->integer('business_id', false, true);
$table->foreign('business_id')->references('business_id')
->on('businesses')->onDelete('cascade');
$table->integer('group_id', false, true);
$table->foreign('group_id')->references('group_id')->on('groups')
->onDelete('cascade');
$table->string('name',50);
$table->string('address',100)->nullable();
$table->string('email',50)->nullable();
$table->timestamps();
});

How can set not null in migration table laravel 5.6

I set user table as below
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->string('password')->nullable();
$table->tinyInteger('status')->unsigned()-> nullable(false) -> change()->default(1);
$table->string('confirmation_code')->nullable();
$table->tinyInteger('confirmed')->unsigned()->nullable(false) -> change()->default(1);
$table->rememberToken();
$table->unsignedInteger('deleted_at');
$table->timestamps();
});
}
but show error as below
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1103 Incorrect table name '' (SQL: alter table `` add `status` tinyint unsigned not null default '1' after `password`, add `confirmation_code` varchar(255) null after `status`, add `confirmed` tinyint(1) not null default '1' after `confirmation_code`, add `deleted_at` timestamp null)
at C:\xampp\htdocs\cron\vendor\laravel\framework\src\Illuminate\Database\Connection.php:664
660| // If an exception occurs when attempting to run a query, we'll format the error
661| // message to include the bindings with SQL, which will make this exception a
662| // lot more helpful to the developer instead of just the database's errors.
663| catch (Exception $e) {
> 664| throw new QueryException(
665| $query, $this->prepareBindings($bindings), $e
666| );
667| }
668|
Exception trace:
1 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1103 Incorrect table name ''")
C:\xampp\htdocs\cron\vendor\laravel\framework\src\Illuminate\Database\Connection.php:452
2 PDO::prepare("alter table `` add `status` tinyint unsigned not null default '1' after `password`, add `confirmation_code` varchar(255) null after `status`, add `confirmed` tinyint(1) not null default '1' after `confirmation_code`, add `deleted_at` timestamp null")
C:\xampp\htdocs\cron\vendor\laravel\framework\src\Illuminate\Database\Connection.php:452
Please use the argument -v to see more details.
please help me to correct this migration.
I think I wrong in not null
You shouldn't be using the ->change() method in Schema::create(), as it will try to change a column that hasn't been created yet. To create a column that allows null values, simply do:
Schema::create("table", function (Blueprint $table) {
$table->string("column"); // Omit ->nullable() to force `NOT NULL`
$table->string("nullable_column")->nullable();
});
When this migration is run, and the table is created, table.column will be initialized with NOT NULL, and table.nullable_column will be initialized as NULL.
Now, if you need to change these in a later migration, that is when you use ->nullable(false)->change();, like so:
Schema::table("table", function (Blueprint $table) {
$table->string("column")->nullable()->change();
$table->string("nullable_column")->nullable(false)->change();
});
Following this migration, table.column will allow NULL, while table.nullable_column will not.

Schema building with foreign keys

I was wondering if someone could show me how to write the following SQL in Laravel 4Schema Builder`?
CREATE TABLE `conversation_reply` (
`cr_id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`reply` text,
`user_id_fk` int(11) NOT NULL,
`ip` varchar(30) NOT NULL,
`time` int(11) NOT NULL,
`c_id_fk` int(11) NOT NULL,
FOREIGN KEY (user_id_fk) REFERENCES users(user_id),
FOREIGN KEY (c_id_fk) REFERENCES conversation(c_id)
);
If I understand what you're asking, this should be close;
Schema::table('conversation_reply', function($table)
{
$table->increments('cr_id');
$table->text('reply')->nullable();
$table->foreign('user_id_fk')->references('user_id')->on('users');
$table->string('ip', 30);
$table->integer('time');
$table->foreign('c_id_fk')->references('c_id')->on('conversation');
});
Do Following:
Below Schema will go inside schema-migrations file under public function up()
//Create ** category table **
Schema:Create ('category',function ($table)){
//Relation: category table id used as FK -> to -> product table category_id
$table->increments('category_id');
//category name
$table->string('category_name',40)->unique();
//time staps: created,Updated
$table->timestamps();
}
Than,Inside product schema:
//Create ** product table **
Schema::create('products', function ($table){
//product id
$table->increments('product_id');
//product name
$table->string('p_name')->unique();
//product description
$table->text('p_description');
//created_at and updated_at column
$table->timestamps();
//Foregine Key
$table->integer('category_id_fk')->unsigned();
//Foreign Key link to category table
$table->foreign('category_id_fk')->references('category_id')->on('category');
}

Resources