artisan migrate error 140 wrong create options - laravel

I've just moved from a Vagrant-based localhost setup to a Docker setup running :
PHP 7.2.8
PHP-FPM 7.2.8
Mariadb 10.2.15 (webhippie/mariadb)
I exec'ed into the Docker machine running FPM and did php artisan migrate, but was greeted with the following error :
SQLSTATE[HY000]: General error: 1005 Can't create table `data`.`migrations` (errno: 140 "Wrong create options") (SQL: create table `migrations` (`id` int unsigned not null auto_increment primary key, `migration` varchar(191) not null, `batch` int not null) default character set utf8mb4 collate utf8mb4_unicode_ci engine = InnoDB ROW_FORMAT=DYNAMIC)
I have another Laravel install running with the same Docker machines and no problem doing migrations.
From the erorr message, it seems there is an error during Laravel's creation of the migrations table. I've no idea what to do next. Help?
UPDATE :
Tried running the creation query :
create table `migrations` (`id` int unsigned not null auto_increment primary key, `migration` varchar(191) not null, `batch` int not null) default character set utf8mb4 collate utf8mb4_unicode_ci engine = InnoDB ROW_FORMAT=DYNAMIC
Removing option ROW_FORMAT=DYNAMIC successfully creates the migrations table. Will removing it impact Laravel's operation?

I think I got the answer.
I set engine = 'innodb ROW_FORMAT=DYNAMIC' at config/database.php. I did this a long time ago when trying to fix Laravel's key too long error. There is a simple fix (in the link) which limits string length to 191. so to fix the problem, just set engine = 'innodb' or engine = 'null' at config/databse.php.

check this out
https://laracasts.com/discuss/channels/eloquent/migrations-and-table-options-row-format?page=0
and let me know if it doesn't work
change config/database.php
'connections' => [
...
'mysql' => [
...
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
]
...

Related

Error on SQLite migrations after upgrade Laravel 5.8 to 6.2

I need some help!
I have an API built in laravel 5.8, i am upgrading the platform to 6.2.
After all changes in configuration files and some scripts php, all my tests witch run the migrations on SQLite is broken.
The following error is displayed:
SQLSTATE[HY000]: General error: 1 no such collation sequence: utf8_general_ci (SQL: CREATE TABLE events (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, event VARCHAR(255) NOT NULL COLLATE BINARY, description CLOB DEFAULT NULL COLLATE BINARY, invitation CLOB DEFAULT NULL COLLATE BINARY, sale CLOB DEFAULT NULL COLLATE BINARY, information CLOB DEFAULT NULL COLLATE BINARY, city VARCHAR(255) NOT NULL COLLATE BINARY,
location VARCHAR(255) NOT NULL COLLATE BINARY, date_start DATE NOT NULL, time_start TIME NOT NULL, date_end DATE DEFAULT NULL, flyer CLOB DEFAULT NULL COLLATE BINARY, atv BOOLEAN DEFAULT '1', created_at DATETIME DEFAULT NULL, updated_at DATETIME DEFAULT NULL, location_map VARCHAR(255) DEFAULT NULL COLLATE utf8_general_ci --IFRAME com a localização do evento.
My intention is update to 7.x after resolve all issues on 6.2.
In the migrations, was enough to remove the collation option from the fields. Example:
Initially this way:
$table->string('field', 255)->charset('utf8')->collation('utf8_general_ci')->change();
The solution was as follows:
$table->string('field', 255)->charset('utf8')->change();
Removing this option will not force a collation not accepted by SQLite.

when i try to import sql file in c panel phpmyadmin - Specified key was too long; max key length is 767 bytes #1071

there are some similar questions but not what i exactly want.
how can i increase this limit. what is file destination where can i replace this number (767 bytes) with another.
-- Dumping structure for table jofr.categories
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(10) unsigned DEFAULT NULL,
`order` int(11) NOT NULL DEFAULT '1',
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `categories_slug_unique` (`slug`),
KEY `categories_parent_id_foreign` (`parent_id`),
CONSTRAINT `categories_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
MySQL said: Documentation
#1071 - Specified key was too long; max key length is 767 bytes
You could set the default string length inside the AppServiceProvider.php file
app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
For more information, you can reference a similar question asked in Stackoverflow
This is a MySQL InnoDB limit, not a PHP one. You can only work around the limit using code, or you can potentially increase the limit using a database option.
The issue is with your index on slug. slug is defined as 255 characters, and you're using utf8mb4, which uses 4 bytes per character, so your index on slug would require 1020 bytes.
There are a couple workaround options.
1. Reduce the size of your field.
Instead of making your slug 255 characters, make it 191. 191 * 4 = 764 < 767. You can do this by specifying the field length in your migration, or by not specifying the length and setting \Illuminate\Support\Facades\Schema::defaultStringLength(191); as mentioned by others.
2. Reduce the size of your index.
You can keep your field size at 255, but tell MySQL to only index the first 191 characters. I don't know if Laravel migrations support this, but you can always try.
$table->index('slug(191)');
3. Enable the innodb_large_prefix database option with DYNAMIC row formats.
The innodb_large_prefix database option increases the key length limit to 3072 bytes. However, this option only affects tables that have a row format of DYNAMIC or COMPRESSED.
If you're on MySQL >= 5.7.7, the innodb_large_prefix option is enabled by default.
If you're on MySQL >= 5.7.9, the default row format is DYNAMIC, and the innodb_large_prefix option is enabled by default, so you wouldn't be having this issue, unless you've changed the defaults.
If you're on MySQL < 5.7.9, the default row format is COMPACT, so you'd need to figure out how to tell Laravel to use the DYNAMIC row format. If you want to do this for all tables, you can set 'engine' => 'InnoDB ROW_FORMAT=DYNAMIC', in your database config. If you only want to do this for one table, you'll need to run raw DB create statements in your migration file.
References:
MySQL create index documentation - information on key size, row formats, and partial indexes
MySQL innodb_large_prefix option
MySQL innodb_default_row_format option
problem is on your unique columns with a length bigger than 191
`slug` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
in this line replace varchar(255) with varchar(191) and this will be resolved
Read this.
edit your AppServiceProvider.php file and inside the boot method set a
default string length:
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}

Why I am getting error for using jsonb keyword in Laravel?

I'm trying to learn Laravel Authorization using following mentioned tutorial:
Tutorial Link.
I'm using mysql database and default collation of the database is utf8mb4_unicode_ci. In Role's Database Migration permissions table data type was jsonb. That statement was:
$table->jsonb('permissions')->default('{}'); // you can check the tutorial link
After giving php artisan migrate --seed command, I am getting following error:
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your S
QL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'json not null
default '{}', `created_at` timestamp null, `updated_at` timestamp ' at line 1 (SQL: create table `roles` (`id` int unsigned
not null auto_increment primary key, `name` varchar(191) not null, `slug` varchar(191) not null, `permissions` json not null
default '{}', `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate 'utf8mb4_unic
ode_ci')
I want to go through similarly like the mentioned tutorial but stuck here. How can I solve this?

Automatic Casting of Default Values on Insert

This may be a feature instead of a bug, so I thought to include it on SO instead of MariaDB's Jira.
Yesterday I updated my MariaDB install on Homebrew from 10.1.23 to 10.2.6. All my selects are still working correctly, but now in my legacy app, I get a bunch of errors on inserts where the code is "assuming" MariaDB will set a default value. For example...
INSERT INTO table SET
email = 'some#email.com', -- varchar
phone_number = '', -- bigint
ts = '2017-05-30 23:51:23', -- datetime
some_val = '689728' -- varchar
This code was working fine before, but since I've upgraded I now get the following couple of errors...
Error 1 (is_some_toggle is a tinyint and is not defined in the query above, it is assumed that MariaDB would just insert a 0)
Field 'is_some_toggle' doesn't have a default value
Error 2 (after I set the default value to is_some_toggle)
Incorrect integer value: '' for column 'phone_number' at row 1
I'm guessing this is a feature, not a bug. I've looked through their changelogs for 10.2 series and I'm not seeing anything jump out, but there's a lot so I could have missed it. I saw a server config for OLD_SQL but that didn't seem to be what I was looking for. Any thoughts?
macOS Sierra 10.12.5 btw
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(200) NOT NULL,
`phone_number` bigint(20) NOT NULL,
`some_val` varchar(6) NOT NULL,
`ts` datetime DEFAULT NULL,
`is_some_toggle` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `email_code` (`email`(15),`some_val`),
KEY `phone_number_code` (`phone_number`,`some_val`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Looks like going through the changelog VERY slowly worked for me.
sql_mode was updated as was outlined in this article.
Option | Old default value | New default value
sql_mode | NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION | STRICT_TRANS_TABLES, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
I changed it back to the default and I'm good as gold.

How to solve SchemaVersionTrackingException in dbdeploy due to no default value in delta_set?

I am trying to do automatic DB migration. I am using dbdeploy for the same.
I followed the steps in this link http://blog.codeborne.com/2012/09/using-dbdeploy-in-gradle.html
I created the change log table as:
CREATE TABLE changelog (
change_number INTEGER NOT NULL,
delta_set VARCHAR(10) NOT NULL,
start_dt TIMESTAMP NOT NULL,
complete_dt TIMESTAMP NULL,
applied_by VARCHAR(100) NOT NULL,
description VARCHAR(500) NOT NULL
);
ALTER TABLE changelog ADD CONSTRAINT Pkchangelog PRIMARY KEY (change_number, delta_set);
The updateDatabase task in build.gradle is:
task updateDatabase << {
ant.dbdeploy(driver: dbDriver,
url: dbUrl,
userid: dbUsername,
password: dbPassword,
dir: './src/main/resources/deploy/sql',
dbms: 'mysql'
)
}
When I do gradle updateDatabase, I get com.dbdeploy.exceptions.SchemaVersionTrackingException: Could not update change log because: Field 'delta_set' doesn't have a default value.
I tried assigning 'main' as default value in the change table log file as:
delta_set VARCHAR(10) NOT NULL DEFAULT 'Main'
But, I still got the same exception.
I also removed the delta_set attribute, I got the same exception. This really confused me.
I am completely new to datamigration. So, any help regarding this error and how I should go about it will be deeply appreciated.
Thank you in advance.
The DBDeploy documentation isn't very explicit about this, but the changelog table format changed between versions 2.X and 3.X (see the upgrade instructions). I suspect that you are using DBDeploy 3.X.
You need to:
Remove the old changelog table:
DROP TABLE changelog;
Recreate it using the new format:
CREATE TABLE changelog (
change_number INTEGER NOT NULL,
complete_dt TIMESTAMP NOT NULL,
applied_by VARCHAR(100) NOT NULL,
description VARCHAR(500) NOT NULL
);
ALTER TABLE changelog ADD CONSTRAINT Pkchangelog PRIMARY KEY (change_number);
After this, everything should work.

Resources