How sol solve this database migration issue? - database

I'm having trouble with Laravel database migration. I have entered foreign key constraint in my database migration file, but when I try to migrate the file it shows this error message.
Illuminate\Database\QueryException : 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 ') on delete cascade on update cascade' at line 1 (SQL: alter table education_qualifications add constraint education_qualifications_teacher_id_foreign foreign key (teacher_id) references teachers () on delete cascade on update cascade)at E:\XAMPP\htdocs\ViduresaApp\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: 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 ') on delete cascade on update cascade' at line 1")
E:\XAMPP\htdocs\ViduresaApp\vendor\laravel\framework\src\Illuminate\Database\Connection.php:452
2 PDO::prepare("alter table education_qualifications add constraint education_qualifications_teacher_id_foreign foreign key (teacher_id) references teachers () on delete cascade on update cascade")
E:\XAMPP\htdocs\ViduresaApp\vendor\laravel\framework\src\Illuminate\Database\Connection.php:452
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateEducationQualificationsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('education_qualifications', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('teacher_id')->nullable();
$table->unsignedInteger('student_id')->nullable();
$table->string('institute_name');
$table->string('user_degree');
$table->string('field_of_study');
$table->string('user_grade');
$table->date('from_date')->nullable();
$table->date('to_date')->nullable();
$table->text('edu_description');
$table->timestamps();
$table->foreign('teacher_id')->references('id')->on('teachers')->onUpdate('cascade')->onDelete('cascade');
$table->foreign('student_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
$table->primary(['teacher_id', 'student_id']);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('education_qualifications');
}
}

You can use both onupdate and ondelete at the same line
For example:
$table->foreign(’author’)->references(’id’)->on(’users’)->onUpdate(’cascade’);

Related

Add column to all tables through migration in Laravel

As our project scaled we decided that every single data should belong to companies that created them. Therefore I'm to add a column "data_owner_company_id" that points to the company that owns given record. Yes it's possible to generate migration to add this column to each model but that is not really feasible since there is 120+ tables & models. How can i tackle this with minimum effort ?
For the model part i figured i can easily apply it to all models by inheritance, but not sure about migration.
TL;DR
How to add int column to all tables by migration ?
Database: MySQL v8
Framework: Laravel 8, PHP 7.3
It's simple if you find all the tables' names in your database, you have to loop and create columns for each and every table.
Try creating columns using queues as it will be a heavy job for 120 tables.
Check the following code:
class CreateDataOwnerCompanyIdtoEachTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up ()
{
$columns = 'Tables_in_' . env('DB_DATABASE');//This is just to read the object by its key, DB_DATABASE is database name.
$tables = DB::select('SHOW TABLES');
foreach ( $tables as $table ) {
//todo add it to laravel jobs, process it will queue as it will take time.
Schema::table($table->$columns, function (Blueprint $table) {
$table->unsignedInteger('data_owner_company_id');
});
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down ()
{
$columns = 'Tables_in_' . env('DB_DATABASE');//This is just to read the object by its key, DB_DATABASE is database name.
$tables = DB::select('SHOW TABLES');
foreach ( $tables as $table ) {
//todo add it to laravel jobs, process it will queue as it will take time.
Schema::table($table->$columns, function (Blueprint $table) {
$table->dropColumn('data_owner_company_id');
});
}
}
}
I'm not 100% sure that it's going to work, but here it goes:
Create class that extends Illuminate\Database\Schema\Blueprint;
In constructor call parent construntor and then
$this->unsignedBigInteger('data_owner_company_id')->nullable();
Use your new class in migrations instead of default Blueprint

Symfony Integrity constraint violation

I tried cascade remove on the 'file' entity that keeps my 'expanse' entity from removing. But this doesn't work.
The error:
Cannot delete or update a parent row: a foreign key constraint fails (zioo.files, CONSTRAINT FK_6354059F395DB7B FOREIGN KEY (expense_id) REFERENCES expenses (id))
The file entity code:
/**
* #ORM\ManyToOne(targetEntity="Expense", inversedBy="files", cascade={"remove"})
* #ORM\JoinColumn(name="expense_id", referencedColumnName="id")
*/
private $expense;
The expanse entity code:
/**
* #ORM\OneToOne(targetEntity="File", cascade={"persist"})
* #ORM\JoinColumn(name="file_id", referencedColumnName="id")
*/
private $file = null;
/**
* #ORM\OneToMany(targetEntity="File", mappedBy="expense", cascade={"remove"})
*/
protected $files;
If a expanse gets deleted the file associated with it should be deleted too.
Using cascade={"remove"} the entity won't be deleted if it is owned by something else. The issue seems to be caused by doctrine, as the expanse entity has 2 relations to file entity and this causes doctrine to "think" that your file entity is owned by something else and not send a delete to database for it, before trying to delete the expanse.
As a result when it tries to delete the expanse this error is thrown.
To test it, remove private $file = null;relation and will see that it will work.
To overcome this, I suggest to use onDelete="CASCADE" on the owning side:
/**
* #ORM\ManyToOne(targetEntity="Expense", inversedBy="files", cascade={"remove"})
* #ORM\JoinColumn(name="expense_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $expense;
In this case, you no longer need cascade={"remove"}:
/**
* #ORM\OneToMany(targetEntity="File", mappedBy="expense")
*/
protected $files;
Doctrine delete relation options

Laravel Eloquent how to create UNIQUE constraint with duplicate NULLs

I'm usinq Laravel 5 with MS Sql Server 2014.
I want to create a unique constraint but it should allow multiple null values.
Here is code I'm using. Where 'passport_no' has to be unique if not null.
Schema::create('UserProfile', function(Blueprint $table){
$table->increments('userprofile_id');
$table->integer('user_id')->unsigned();
$table->string('passport_no', 50)->unique()->nullable();
$table->foreign('user_id')->references('id')->on('users')
->onUpdate('cascade')->onDelete('cascade');
});
This is an ancient question, but sill needs answering. As stated above, SQL Server from 2008, including Azure SQL, supports a special index that will work around it. In your database migration you can check the driver used and substitute the database builder standard SQL with an MSSQL-specific statement.
This migration example is for Laravel 5+, and creates a users table with a unique, but nullable, api_token column:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
$table->string('name', 100)->nullable()->default(null);
// etc.
$table->string('api_token', 80)->nullable()->default(null);
if (DB::getDriverName() !== 'sqlsrv') {
$table->unique('api_token', 'users_api_token_unique');
}
});
if (DB::getDriverName() === 'sqlsrv') {
DB::statement('CREATE UNIQUE INDEX users_api_token_unique'
. ' ON users (api_token)'
. ' WHERE api_token IS NOT NULL');
}
}
you can use a unique Index and in its filter set your condition like
passport_no is not null
in this way you can solve your problem

Error in a FOREIGN KEY constraint that i not called

Tecnologies: ASP.Net MVC 3, Entity Framework 4, SQL Server 2012.
When i try insert a new entity in my database, the entity framework gives that error:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Cep_Cidade". The conflict occurred in database "CloudWorkLJEletro", table "dbo.Cidade", column 'ID'.
The statement has been terminated.
The problem is that table dbo.Cidade or any association with this table is not called in my operation. Why do I get this error if I'm not performing any operation on this table or in your relationships.
Database scheme:
And My code:
public void SaveContrato(Contrato Contrato, int id)
{
try
{
Contrato.Endereco = null;
Contrato.ID_ENDERECO = null;
context.AddToContrato(Contrato);
context.SaveChanges();
}
catch (Exception ex)
{
throw ex;
}
}

HibernateException: Missing table error for a Join Table using Grails 2.0.2 on MS SQL legacy database

I am trying to get a many-to-many relationship working using Grails 2.0.1 on Windows 7. I have exhausted both Google, this site, and my Grails books. Nothing worked. I am connecting to a MS SQL Server 2005 database that I have READ only privileges on and yes - it is a legacy database. Everything in the 2 individual tables works fine (views OK & all) but when I try to add the join table code I get an error:
org.hibernate.HibernateException: Missing table: dbo.IN_USR_DRAWING_PRIV
The table does indeed exist and I can see it fine using IntelliJ's IDEA 10.5 Data Sources view & the MS SQL Server Management Studio. The relevant part of the error is this (I can send more ... much more if needed) :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.HibernateException: Missing table: dbo.IN_USR_DRAWING_PRIV
Here are the 2 domain classes :
class Drawing {
static hasMany = [appusers:Appuser]
String id
String drawingId //this is in the join table
String drawingName
static transients = ['name']
void setName(String name) {
id = name
}
String getName() {
return id
}
static mapping = {
table name: "IN_DRAWING", schema: "dbo"
version false
id column: 'DRAWING_ID', generator:'identity', insertable:false, updateable:false
drawingId column: "`DRAWING_ID`",insertable:false, updateable:false //this is in the join table
drawingName column: "`DRAWING_NAME`"
appusers column: '`USR_ID`',
joinTable: 'IN_USR_DRAWING_PRIV'
}
}
class Appuser {
static belongsTo = Drawing
static hasMany = [drawings:Drawing]
String id
String usrId //this is in the join table
String usrName
static transients = ['name']
void setName(String name) {
id = name
}
String getName() {
return id
}
static mapping = {
table name: 'IN_USR', schema: "dbo"
version false
id column:'USR_ID', generator:'identity', insertable:false, updateable:false //this is in the join table
drawings column: 'DRAWING_ID',
joinTable: 'IN_USR_DRAWING_PRIV'
usrName column: "`USR_NAME`"
}
}
And here is the schema for the join table:
dbo.IN_USR_DRAWER_PRIV
USR_ID (PK, varchar(23), not null)
DRAWING_ID (PK, FK, varchar(23), not null)
PRIV_ID (PK, int, not null)
GRAG reports it has a composite key of all 3 columns, which it does along with a FK on DRAWING_ID.
Solutions that I have tried :
This code (which fails with the "Missing Table" exception.
Adding a domain controller for the join table - same result.
Any hints/clues/solutions appreciated.
I fixed this by using Groovy SQL directly and passing in the T-SQL.

Resources