Is it possible to join a MS-SQL to MySQL in Laravel - php

I apologize if this is a silly question. This is probably well out of standard practice, but I'm looking to be able to join data from a MS-SQL database with that of MySQL in Laravel 5.2.
I'm not sure if it's possible to do something like...
\DB::connection('sqlsrv')->table('mstable')
->leftJoin(\DB::connection('mysql')->table('mysqltable'),
'mysqltable.shared_id',
'=',
'mstable.shared_id');
My thinking is that if Laravel is converting the query early enough into a PHP object, it should be able to. Otherwise, is there a fallback to being able to use the two database types together?

I'm pretty sure that a join won't be possible. What you can do though, is using relations on different databases. Depending on your situation this might be an applicable workaround. I am currently using this approach to query entities from different databases and "chunk" them so that I only keep a couple of thousand entities in the memory. It's still an efficient way to iterate over all entities, because I'm using eager loading, so that Laravel / Eloquent only triggers two requests per chunk: One to get the primary models and the second to get the relation (by default this is done by an IN statement on the relation's table using the keys obtained from the primary models table).
A "simple" way to set this up is to fill the protected $connection property of the Eloquent Models like this:
class Foo extends Model{
protected $connection = "mysql";
public function bar(){
return $this->hasOne(Bar::class);
}
}
class Bar extends Model{
protected $connection = "ms-sql";
}
Foo::with("bar")->get();

Related

How can I utilize a table and a view within a single Eloquent model based on the SQL statement?

Using Laravel 5.1, I have created an Eloquent Model:
class Divisions extends Model
{
}
I have a table and a view in my database which are relevant to this model.
divisions_info - The table, it will have INSERT and UPDATE queries run, but will never have a SELECT run on it.
divisions_view - The view, it will have SELECT queries run only (obviously).
The reason for the segmentation is that the divisions_view view joins with data from the divisions_info table and from another relevant, read-only table in an adjacent database.
I would like to utilize one model for everything that deals with divisions, but direct any UPDATE/INSERT queries on the divisions_info table and all SELECT queries on the divisions_view view.
The Laravel documentation allows you to override the assumed table name, like so:
protected $table = 'divisions_info';
However, this takes precedence over the entire model. I would like to be able to utilize all the built in methods that come with using the Eloquent model, but have it split accordingly across SQL statements.
Is this possible? If so, what is the right way to achieve it?
If it is not possible, without diving into opinion, what is the most logical/Laravel-esque way to work with the same data in two different locations?
This might be a solution:
use Illuminate\Database\Eloquent\Model;
class Division extends Model {
public function scopeFromView($query)
{
return $query->from('divisions_view');
}
}
Just call the fromView() method in any part of the query like this:
Division::fromView()->get();

Moving data Postgres to MySQL using PHP/Laravel5

I'm using:
A local Postgres DB
Laravel 5 with a MySQL DB also local
Postgres DB contains the table structure from OTRS - with over 91.000 rows on the table "tickets"
I needed to move the data from one DB to the other. What I did was compile a big query that united all the data I needed and run it in a PHP script I created inside the Laravel structure. Then I iterated through the results using Eloquent to insert into MySQL. I know it's terrible but I had to remove the memory and time limits for PHP in order to do this and though it took a really long time, it worked!
Right now I realized I missed something, I need to rerun a similar query (results in the same number of rows), but this time to just add one field on the MySQL DB.
My question is, how can I optimize this process? I'm thinking of using chunks but I don't know how to that.
To clarify:
MySql's Tickets table contains 91397 rows and 5 columns
Postgres Tickets table also has 91397 rows and 6 columns
I created a migration on Laravel (MySQL) that added the extra column (though it's empty)
It's probably easier if I show you the code I have.
link
You can use eloquent to do this. Here's how I'd do (untested, may need some tuning):
Set up both DB connections in the config\database.php.
Make two models for the same resource (you can use only one model but I rather not), I'll name them M1 and M2, with different connection attribute. To do this create an attribute inside the model: protected $connection = 'connection_name'.
So basically:
class M1 extends Model {
protected $connection = 'connection_name';
protected $table = 'table_name';
protected $guarded = [];
Same for M2 with a different $connection.
Now in your controller method or wherever you're executing your code, you can chunk queries using eloquent:
//assuming you are transferring M1's db to M2's
M1::chunk(200, function($m1s) //if you wanna use only one model, this should be M1::on('connection-name')->chunk(...
{
foreach ($m1s as $m1)
{
$m2 = new M2();
//this does not copy model-specific attributes like $connection
$m2->fill( $m1->getAttributes() );
$m2->save();
}
});
I think this does the job, can you test this?

How to access db views using Laravel models?

I am porting a Postgres-backed web app to Laravel 4.2, and I can't see a way to utilize the existing eight or so summation views which are built in the psql db. These views preform various aggregation and averaging functions, and as such are properly part of the schema as they illustrate the relationships between the table entities.
Surely someone has had to use db views with the active record style interface of Laravel? How do you go about it?
Your question is about database views and if I'm not wrong then you are talking about the dynamic table that gets created on the fly, for example, in MySql, it's possible to create a View using something like this:
CREATE VIEW students AS SELECT * FROM profiles where type='student' ORDER BY id;
So, it'll allow to query the dynamic table which is the students view here, for example:
select * from students;
This will return the filtered data from students view. So, if I'm right about your question then I think you are able to use Eloquent just like you use for real tables, for example, to create an Eloquent model for students view you can simply create it using something like this:
class ViewStudent extends Eloquent {
protected $table = 'students';
}
So, now you can use this model as usully you may use for other tables, for example;
$students = ViewStudent::all();
It's just the same way. Since you asked for psql so I'm not sure about the syntax of that or how it works in that system but I believe it's possible same way.

Get eloquent model and all its relationships with one query in Laravel

The problem
Is there a way to get an eloquent model and all its relationships using only one query?
Example scenario:
You have both Post and Comment Eloquent models.
You add their relationships in the model class using hasMany('Comment') and belongsTo('Post') respectively.
Now this is what i've been doing to retrieve both the post AND its comments:
$post = Post::find($id);
$post->comments;
return $post;
This returns a beautiful jsonobject. The problem is, this way, i would be using two queries. That's not so great.
Workaround
Two alternatives come to mind:
Using joinstatements in order to make the query i want. But Eloquent is so much more elegant.
Leveraging the Cache class in order to make even fewer queries in the future (this, i will do anyway later on).
Any ideas?
In eloquent you can do it like this
$post = Post::with('comments')->find($id);
return $post;
Edit:
This will not run the query with join in mysql but its just a single query in Eloquent.

How can I join tables in Zend while using a class that inherits from Zend_Db_Table_Row_Abstract?

I have a class that extends Zend_Db_Table lets call it 'Users' that uses the class 'User' (inheriting from Zend_Db_Table_Row_Abstract) as its rowClass. I need it this way because User has additional methods that I use.
As far as I know it is not possible to join tables inside my Users class so I use:
$query = $db->select();
$query->from(...);
$query->joinInner(...);
instead of
$this->select(); ...
But then of course the rows I get are not of the User class. So I would like to know how can I force my query to return User objects instead of Row objects.
Another way would be to get Zend_Db_Table to make that join in which case I would also get what I want.
Quoting David Caunt's answer in linked duplicate:
Because Zend_Db_Table provides row gateway functions, which don't work if you join on other tables, you have to state that you are willing to give it up. Simply make a call to setIntegrityCheck and it will work:
$select->setIntegrityCheck(false);

Categories