mariaDB JSON support in Laravel - php

I'm trying to create a json database in XAMP, while using the phpmyAdmin it showed me that I'm using mariaDB but in my xamp-control panel v3.2.2 it shows running mySQL on port 3306. I'm using Laravel 5.4 framework to create the database, following is my migration which I'm trying to execute:
Schema::connection('newPortal')->create('pages', function (Blueprint $table){
$table->increments('id');
$table->string('title');
$table->string('slug')->unique()->index();
$table->json('styles')->nullable();
$table->json('content')->nullable();
$table->json('scripts')->nullable();
$table->softDeletes();
$table->timestamps();
});
Now while executing this I'm getting following error:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'json null, content json null, scripts json null, deleted_at timestamp null' at line 1 (SQL: create table pages (id int unsigned not null auto_increment primary key, title varchar(191) not null, slug varchar(191) not null, styles json null, content json null, scripts json null, deleted_at timestamp null, created_at timestamp null, updated_at timestamp null) default character set utf8mb4 collate utf8mb4_unicode_ci)
Even if I keep not null it throws the same error. I want to have json formatted data, I checked the supported version and as per the documentation json format support started from the version MariaDB 10.0.16. and I'm using 10.1.21-MariaDB
Help me out in this.

Since MariaDB version 10.2.7; theJSON data-type is an alias for LONGTEXT.
If you are having issues with the JSON data-type in MariaDB, simply just change it to LONGTEXT. ;-)
Or add MariaDB JSON to Laravel with this package

Note that the 1064 complained about the datatype "json". Such is not (yet) implemented in MariaDB.
You can get close with Dynamic Columns, which at least has a way of fetching them into JSON syntax.
Another thing (probably what you are referring to) is CONNECT being able to have a JSON table type. (Not column type.)
MySQL 5.7 has a datatype called JSON, plus a bunch of functions to manipulate such.

Figured out a simple workaround (not recommended for production) -
As per mariadb version 10.1.32 and lower it seems like mariadb does not support json data type I am still unsure if it is available in version 10.2.7+.
but here's a simple workaround to get through this.
change json data type into text and then run your migration again.
(https://user-images.githubusercontent.com/27993070/41234555-19c5d1d8-6dbf-11e8-9a4b-0644b03aecfc.png)
source-
https://github.com/laravel/framework/issues/13622

Add MariaDB JSON support to Laravel by running this command using composer:
composer require ybr-nx/laravel-mariadb
If you are using Larvel 5.3 and 5.4 do these two items:
Include MariaDBServiceProvider in config/app.php by adding this
line to providers:
'providers' => [
// other exist providers
YbrNX\MariaDB\MariaDBServiceProvider::class,
]
Set default connection in database configuration to mariadb:
'defaultconnection' => [
'driver' => 'mariadb',
Adding package is done and then you can use functionalities.
In Migrations:
$table->json('field') //CHECK (JSON_VALID(field))
$table->json('field')->nullable() //CHECK (field IS NULL OR JSON_VALID(field))
For Query builder:
$query->where('somejson->something->somethingelse', 2)
DB::table('sometable')->select('sometable.somedata', 'sometable.somejson->somedata as somejsondata')
Also, JSON_SET() works in MariaDB as in MySQL 5.7:
DB::table('sometable')->where('somejson->somedata', $id)->update(['somejson->otherdata' => 'newvalue']);
Note 1: MariaDB has an alias for JSON datatype since version 10.2.7
Note 2: There is bug in MariaDB < 10.2.8 JSON_EXTRACT() behaviour
function. It's fixed in MariaDB 10.2.8
retrieved from

Related

Laravel 5.5 migration fails: Update column datatype string to json

When I migrate my db I get a error on updating a table column from string to JSON.
The column value is like:
{"images":["/vendors/57/horse-16.png"]}
I checked if this is a valid JSON and that looks good to me..
My migration file is:
public function up()
{
Schema::table('vendor_horses', function (Blueprint $table) {
$table->json('image')->change();
});
}
My error in Laravel:
SQLSTATE[42000]: Syntax error or access violation: 1253 COLLATION 'utf8mb4_
unicode_ci' is not valid for CHARACTER SET 'binary' (SQL: ALTER TABLE vendo
r_horses CHANGE image image JSON DEFAULT NULL COLLATE utf8mb4_unicode_ci)
I don't know what's wrong, the strings are json correct so why does the update fails?
I dig some issues related to the error in Github and found that when changing into a JSON field, the collation should be set to an empty string and this issue will be solved. So you can try by changing the below code:
$table->json('image')->change();
to
$table->json('image')->customSchemaOptions(['collation' => ''])->change();
For more details you can check this issue
$query = "ALTER TABLE tablename MODIFY image JSON DEFAULT NULL";
\Illuminate\Support\Facades\DB::statement($query);
Try this in laravel migration.. working for me

Eloquent: Invalid default value with timestamps

Here's my migration schema:
public function up()
{
Schema::create('objects', function (Blueprint $table) {
$table->increments('id');
$table->timestamp('timestamp1');
$table->timestamp('timestamp2');
});
}
But when I execute php artisan migrate, I get this error:
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'timestamp2' (SQL: create table objects (id int unsigned not null auto_increment primary key, timestamp1 timestamp not null, timestamp2 timestamp not null) default character set utf8mb4 collate utf8mb4_unicode_ci)
I must indicate that when I remove one of the 2 $table->timestamp(...); lines it works, but it doesn't when there is both. And the Object.php model is empty as it can be. Did I make a mistake?
I have read this post, but even though there is no longer errors when I change timestamp(...) into dateTime(...), I only want timestamps.
Timestamps are a little special, they must either be nullable or they must have a default value. So you must choose between timestamp('timestamp1')->nullable(); or timestamp('timestamp1')->useCurrent() or a custom default value like timestamp('timestamp1')->default(DB::raw('2018-01-01 15:23')).
I found this solution on laracasts:
nullableTimestamps() are only for default fields created_at, updated_at. for custom fields use timestamp()->nullable();
You can make one of the two timestamps nullable by using
timestamp()->nullable();
using your example, you would use:
$table->timestamp('timestamp2')->nullable();
Also laravel has built in timestamps by using
$table->timestamps();
which would automatically handle updated_at and created_at timestamping for you

MSSQL Server INSERT NULL, but insert GetDate() in DATETIME

I am migrating a database from MySQL to MSSQL.
[MySQL] I have a CHANGEDATE column that is of TIMESTAMP with default CURRENT_TIMESTAMP
[MSSQL] I have the same CHANGEDATE column that is of DATETIME and added a default constraint of GETDATE()
The codebase is PHP using CodeIgniter. I want the column to always be set so I don't allow NULL in either DBMS.
When I insert with MySQL, the property of the PHP model CHANGEDATE defaults to NULL. This triggers the default and the column entry is set to CURRENT_TIMESTAMP. The same code when configured to MSSQL however throws an error that NULL is not allowed in the column, which is valid, but I would rather MSSQL function like MySQL and insert the value of GETDATE() in that instance.
If I do unset($model->CHANGEDATE) or delete the property from my model, then it works as expected, but I wanted to know if there was a way to solve this just using MSSQL instead of updating all my PHP models.
class model {
public $CHANGEDATE;
...
}
ERROR (as described):
[Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Cannot insert the value NULL into column 'CHANGEDATE'; column does not allow nulls. INSERT fails.
INSERT INTO Logs (..., CHANGEDATE, CHANGEBY) VALUES (..., NULL, NULL)
UPDATE:
CI should create support for DBMS specific keywords as #steoleary stated in his answer(for which I marked his correct). However, I found the best solution in my case was to slightly modify the core class DB_active_rec.php
function set(...){
...
foreach ($key as $k => $v)
{
if (is_null($v)) continue;
...
}
}
I assume that you already have the default set on your SQL server column and you don't allow NULLs, deafult constraints won't fire on a NULL value, they will only fire when no value is specified, or if you specify to insert the default value on insert like this:
INSERT INTO [dbo].[table]
([col1]
,[col2]
,[col3]
,[col4]) --Column with default constraint
VALUES
('bob',
'bobson',
1,
DEFAULT) --default keyword
Doing that will cause the default to fire and you shouldn't have to change your models.
I don't know how to express this in code igniter, but in SQL Server, it is really easy:
create table . . . (
changedate not null datetime default getdate()
)
No trigger is required.

mysql error 'TYPE=MyISAM'

Below query I'm executing in Ubuntu 12, MySQL 5.1 version and receiving error as mentioned:
CREATE TABLE mantis_config_table (
config_id VARCHAR(64) NOT NULL,
project_id INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL DEFAULT 0,
access_reqd INTEGER DEFAULT 0,
type INTEGER DEFAULT 90,
value LONGTEXT NOT NULL,
PRIMARY KEY (config_id, project_id, user_id)
) TYPE=MyISAM;
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TYPE=MyISAM' at line 9
Can anyone suggest what's wrong?
Replace
TYPE=MyISAM
with
ENGINE=MyISAM
The problem was "TYPE=MyISAM" which should be "ENGINE=MyISAM" as per MySQL version updates - a simple search / replace has fix it.
Do not use the keyword TYPE anymore. Use ENGINE instead.
TYPE keyword is depreciated (since 5.0) and not supported in MySQL5.5
CREATE TABLE mantis_config_table
(
...
)
ENGINE = MyISAM;
^^^^^^--------------------- HERE
In newer MySQL Versions its:
ENGINE=MyISAM
here the tutorial (MySQL)
Use ENGINE instead of TYPE
ENGINE = MYISAM ;

Symfony: creating invalid MySQL code?

I'm reading the Symfony documentation (Practical Symfony), and I finished creating the SQL code with propel.
But when i try to
$ symfony propel:insert-sql
the MySQL complains with:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Type=InnoDB' at line 7
Snippet of the produced MySQL code:
CREATE TABLE `jobeet_category` (
`id` INTEGER NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 255 ) ,
PRIMARY KEY ( `id` ) ,
UNIQUE KEY `jobeet_category_U_1` ( `name` )
) TYPE = InnoDB;
So the problem is TYPE = InnoDB;, but I don't understand why did propel produce invalid code.
I followed all the instructions in the book, I'm not sure what could be the problem - maybe the MySQL version I have?
Edit: I found my answer. http://zippykid.com/2010/05/symfony-mysql5-5-error/
I'm pretty sure it should be ENGINE = InnoDB instead of type.

Categories