Fetch data from 2 tables without relationship in doctrine - mysql

I'm new to Symfony2. It suggested to use doctrine so I'm learning it.
Now I am testing to fetch data from 2 tables. Suppose table names are tb_info & tb_group. I've 2 classes with same name with proper ORM that represents these 2 tables.
In simple query, we do
"SELECT * FROM tb_info,tb_group"
And all the magical data come to my hand. Now with Doctrine I can't find simple way like this. I tried
$query = $em->createQuery(
'SELECT p
FROM AcmeDbBundle:tb_info,AcmeDbBundle:tb_group p'
);
This doesn't work. I saw some ways to collect data from 2 different tables. But I don't want to use relationship.
Is there any simple ways to write query in doctrine to fetch data from multiple tables?? Am I missing anything?

You can use Doctrine QueryBuilder in a repository function:
$queryBuilder = $this->_em->createQueryBuilder();
$queryBuilder->addSelect("position,candidate")
->from("RadsphereRecruitmentBundle:Position", 'position')
->from("RadsphereRecruitmentBundle:Candidate", 'candidate')
->andWhere("position.open = :open")
->setParameter("open",true);
return $queryBuilder->getQuery()->getResult();

Related

TypeORM: how to load relations with CreateQueryBuilder, without using JOINs?

I'm developing an API using NestJS & TypeORM to fetch data from a MySQL DB. Currently I'm trying to get all the instances of an entity (HearingTonalTestPage) and all the related entities (e.g. Frequency). I can get it using createQueryBuilder:
const queryBuilder = await this.hearingTonalTestPageRepo
.createQueryBuilder('hearing_tonal_test_page')
.innerJoinAndSelect('hearing_tonal_test_page.hearingTest', 'hearingTest')
.innerJoinAndSelect('hearingTest.page', 'page')
.innerJoinAndSelect('hearing_tonal_test_page.frequencies', 'frequencies')
.innerJoinAndSelect('frequencies.frequency', 'frequency')
.where(whereConditions)
.orderBy(`page.${orderBy}`, StringToSortType(pageFilterDto.ascending));
The problem here is that this will produce a SQL query (screenshot below) which will output a line per each related entity (Frequency), when I want to output a line per each HearingTonalTestPage (in the screenshot example, 3 rows instead of 12) without losing its relations data. Reading the docs, apparently this can be easily achieved using the relations option with .find(). With QueryBuilder I see some relation methods, but from I've read, under the hood it will produce JOINs, which of course I want to avoid.
So the 1 million $ question here is: is it possible with CreateQueryBuilder to load the relations after querying the main entities (something similar to .find({ relations: { } }) )? If yes, how can I achieve it?
I am not an expert, but I had a similar case and using:
const qb = this.createQueryBuilder("product");
// apply relations
FindOptionsUtils.applyRelationsRecursively(qb, ["createdBy", "updatedBy"], qb.alias, this.metadata, "");
return qb
.orderBy("product.id", "DESC")
.limit(1)
.getOne();
it worked for me, all relations are correctly loaded.
ref: https://github.com/typeorm/typeorm/blob/master/src/find-options/FindOptionsUtils.ts
You say that you want to avoid JOINs, and are seeking an analogue of find({relations: {}}), but, as the documentation says, find({relations: {}}) uses under the hood, expectedly, LEFT JOINs. So when we talk about query with relations, it can't be without JOIN's.
Now about the problem:
The problem here is that this will produce a SQL query (screenshot
below) which will output a line per each related entity (Frequency),
when I want to output a line per each HearingTonalTestPage
Your query looks fine. And the result of the query, also, is ok. I think that you expected to have as a result of the query something similar to json structure(when the relation field contains all the information inside itself instead of creating new rows and spread all its values on several rows). But that is how the SQL works. By the way, getMany() method should return 3 HearingTonalTestPage objects, not 12, so what the SQL query returns should not worry you.
The main question:
is it possible with CreateQueryBuilder to load the relations after
querying the main entities
I did't get what do you mean by saying "after querying the main entities". Can you provide more context?

Laravel: eloquent select * vs select column

In my Laravel API everyone and everywhere written select *, even when it does not need to collect all the column data.
Is it better to use eloquent select instead, specifying exactly what's needed?
There are several ways of doing this:
To select only specific fields you can do something like:
ModelName::all('column1', 'column2', 'column3');
Or using get:
ModelName::get(['id', 'date']);
For Models with relationships:
$model->relation()->only(['column1', 'column2']);
If you need to eager load while selecting specific columns with relationship:
$data = Model::with(array('relation' => function($query)
{
$query->select('name');
}))->get();
You can read more at collections

SqlAlchemy table name reflection using an efficient method

I am using the code below to extract table names on a database at a GET call in a Flask app.:
session = db.session()
qry = session.query(models.BaseTableModel)
results = session.execute(qry)
table_names = []
for row in results:
for column, value in row.items():
#this seems like a bit of a hack
if column == "tables_table_name":
table_names.append(value)
print('{0}: '.format(table_names))
Given that tables in the database may added/deleted regularly, is the code above an efficient and reliable way to get the names of tables in a database?
One obvious optimization is to use row["tables_table_name"] instead of second loop.
Assuming that BaseTableModel is a table, which contains names of all other tables, than you're using the fastest approach to get this data.

SugarCRM 7 SugarQuery() join statement with custom modules

I'm trying to write a simple query in Sugar 7.2 that will join a table. This SQL is what I'm trying to create in the Sugar framework using SugarQuery().
SELECT * FROM keyname_table_a LEFT JOIN keyname_table_b
So what I've created is the following. It works just fine when I use the core modules, but if I switch it to custom modules that we've created, Sugar logs me out and brings me to a login prompt.
$query = new SugarQuery();
$query->from(BeanFactory::getBean('keyname_table_a'));
$query->join('keyname_table_b');
$results = $query->execute();
return print_r($results, true);
The above logs me out and gives me the following error message in a popup message (similar to how app.alert.show works), and logs me out.
Error: Request failure, or, missing/invalid parameter. Please contact technical support
If I replace the "from" and "join" tables to be "Accounts" and "cases" respectively, then the query works just fine and pulls in the expected result. However, switching it to the custom modules that we have results in the above error and we are logged out instantly.
I have verified that the relationship exists and there is data linking the two together. It is a one to many relationship in Sugar. table_a is one, while table_b is many.
What is the proper way to join two custom modules with the SugarQuery() object?
You need to pass link field name instead of table_name or relationship name
$query = new SugarQuery();
$query->from(BeanFactory::getBean('keyname_table_a'));
$query->join('link_name');
$results = $query->execute();
The join should be the relationship name. If you would like to join a table directly you can use joinTable().
In the Accounts example above, cases is the relationship name, not the table name.
Have a great day!

CakePHP database query - am I overcomplicating things?

So, I need to search a real estate database for all homes belonging to realtors who are part of the same real estate agency as the current realtor. I'm currently doing this something like this:
$agency_data = $this->Realtor->find('all',array(
'conditions'=>
array(business_name'=>$realtor_settings['Realtor']['business_name']),
'fields'=>array('num'),
'recursive'=> -1
));
foreach($agency_data as $k=>$v){
foreach($v as $k=>$v1){
$agency_nums[] = $v1['num'];
}
}
$conditions = array(
'realtor_num'=>$agency_nums
);
It seems a bit crazy to me that I'm having to work so hard to break down the results of my first query, just to get a simple, one-dimensional array of ids that I can use to build a condition for my subsequent query. Am I doing this in an insanely roundabout way? Is there an easy way to write a single CakePHP query to communicate "select * from homes where realtor_num in (select num from realtors where business_name = 'n')"? If so, would it be any more efficient?
For sure it's complicated (in your way) :)
Depending from the results you can do following:
$agency_data = $this->Realtor->find('list',array(
'conditions'=>array('business_name'=>$realtor_settings['Realtor']['business_name']),
'fields'=>array('num', 'num'),
'recursive'=> -1
));
$agency_data; //this already contain array of id's
Method 2 - building a sub query there are 2 ways strict and not so strict :) The first one you can see here (search for Sub-queries).
The other option is to have following conditions parameter:
$this->Realtor->find('all', array('conditions'=>array('field in (select num from realtors where business_name like "'.$some_variable.'"))));
Of course be careful with the $some_variable in the sub-query. You shold escape it - use Sanitize class for example.
$agency_data = $this->Realtor->find('all',array(
'conditions'=>
array('business_name'=>$realtor_settings['Realtor']['business_name']),
'fields'=>array('num'),
'recursive'=> -1
));
$conditions = Set::extract("{n}.Realtor.num", $agency_data);
I would use something like Set::extract to grab the list of data you are looking for. The advantage of doing it this way is that you can reuse the same dataset in other places and save queries. You could also write the set::extract statement in this format:
$conditions = Set::extract("/Realtor/num", $agency_data);