Basic laravel hasMany relation doesn't work out of the box for postgres?
I'm trying this:
$categories = Category::with('products')->get();
where products relation is:
public function products()
{
return $this->hasMany(Product::class, 'category_id', 'id');
}
SQL query which it tries to make looks like:
select
*
from
"products"
where
"products"."category_id" IN (...)
which is not a valid syntax for postgres
Am I missing something? Driver is set to pgsql
The error I'm getting is:
Undefined function: 7 ERROR: operator does not exist: character varying = integer LINE 1: ...
* from "products" where "products"."category_id" in (13, 14...
^ HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
Related
This question already has answers here:
How make doctrine findby to json field without native query
(2 answers)
Symfony Doctrine Expected known function, got 'JSON_GET_TEXT'
(1 answer)
Doctrine query postgres json (contains) json_array
(1 answer)
Closed 10 months ago.
I have my roles of my users with type json and I would like to get the list of users by roles.
/**
* #ORM\Column(type="json")
*/
private $roles = [];
$queryBuilder
->where("$rootAlias.roles LIKE :role")
->setParameter('role', '["ROLE_USER"]')
;
This is the error I get:
An exception occurred while executing a query: SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: json ~~ unknown\nLINE 1: ...ce s1_ ON u0_.service_id = s1_.id WHERE u0_.roles LIKE $1 OR...\n
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
It works great like this "roles"::TEXT LIKE :role but I don't know how to convert "roles"::TEXT in query builder?
To work with json, you can use the DoctrineJsonFunctions extension.
Installation
composer require scienta/doctrine-json-functions
Declare a function in config/packages/doctrine.yaml
orm:
dql:
string_functions:
JSON_GET_TEXT: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Postgresql\JsonGetText
Now you can write such a request in your UserRepository
public function getUsersByRole($role){
return $this->createQueryBuilder('u')
->where("JSON_GET_TEXT(u.roles,0) = :role ")
->setParameter('role', $role)
->getQuery()
->getResult();
}
SQLSTATE[42883]: Undefined function: 7 ERROR: function sum(character varying) does not exist
LINE 1: select sum("amount") as aggregate from "payments"
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts. (SQL: select sum("amount") as aggregate from "payments")
PDOException
SQLSTATE[42883]: Undefined function: 7 ERROR: function sum(character varying) does not exist LINE 1: select sum("amount") as aggregate from "payments" ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
It's a Laravel Project and working fine locally, but throwing this error on Heroku, please kindly assist.
This is my code: $totalAmount = DB::table('payments')->sum('amount');
Its working fine locally.
For others facing this same issue.
Firstly, sum() does not accept varchar or string( if your column data type is varchar/string you will get that error ).
You can change your data type to integer or double( or the likes ).
Write you code like this $totalAmount = Payment::select(DB::raw('sum(cast(amount as double))'))->get(); ( remember get() will return and array )
or $totalAmount = DB::raw('SUM(amount)'); instead of $totalAmount = DB::table('payments')->sum('amount'); ( but you can write it like this if you will go for the first option to change data type)
For me I changed data type to integer and use this $totalAmount = DB::table('payments')->sum('amount');
Why is it so that every time I try to post an empty input that has an integer as data type within my migration(s), I get this error:
SQLSTATE[HY000]: General error: 1366 Incorrect integer value
My migration:
public function up()
{
Schema::table('dossiers', function (Blueprint $table) {
$table->integer('amount_of_cilinders')->nullable();
$table->integer('amount_of_doors')->nullable();
$table->integer('manufacturing_year')->nullable();
$table->integer('manufacturing_month')->nullable();
$table->date('date_first_admission')->nullable();
$table->integer('weight')->nullable();
$table->integer('power')->nullable();
});
}
My controller:
public function update(Request $request, Dossier $dossier)
{
$this->validate($request, [
'date_first_admission' => 'date',
]);
$dossier->update($request->all());
return redirect('/dossiers/' . $dossier->id);
}
Update:
I decided to change the datatype to string since I'm not using these columns anywhere else..
E.g. $table->string('power')->nullable();
This may be happening because of MySQL is running in strict mode.
Run the following queries in the MySQL CLI, to check if the database is in strict mode:
SELECT ##GLOBAL.sql_mode;
SELECT ##SESSION.sql_mode;
If it has something containing STRICT_TRANS_TABLES you could try and run:
SET ##global.sql_mode= 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Null doesn't mean empty string. Either add ->default(0) to all your columns in your migration.
$table->integer('power')->default(0)->nullable();
OR
Use a mutator in your model, do a check before you pass the value:
public function setPowerAttribute($value){
$this->attributes['power'] = (empty($value) ? 0 : $value);
}
When you use nullable(), means default set NULL. So make it default 0 as like below:
$table->integer('COLUMNNAME')->default(0);
I may be completely off, but AFAIK empty values are invalid in numerical fields. Probably the value returned by the input is an empty string if you do not enter anything. This would trigger the SQL error, since you may either
pass a valid numerical value, like "0", oder
pass a NULL value (if nullable is true - see SQL "three state" logic)
An empty string is neither 0, nor is it NULL.
Maybe this article helps you, it deals with a similar oddity when using validation rules, I guess this could be another apperance of this behavior.
https://github.com/laravel/framework/issues/11452
Armin.
I have this problem in a query using laravel groupBy, it simply return a groupBy error. I have read the documentation about this but can't really figure it out. I also read the same problem pointing that it is because of postgreSQL that I need to include all the columns in grouBy clause. I tried it but still it doesn't return the distinct values. Please help me with this. Below is my code. Thanks a lot.
Controller function
public function index(){
$purchases = Purchase::groupBy('purchase_order_id')->get();
return view('purchases/purchases_crud', ['allPurchases' => $purchases]);
}
Table to query
Error
QueryException in Connection.php line 680:
SQLSTATE[42803]: Grouping error: 7 ERROR: column "purchases.id" must appear
in the GROUP BY clause or be used in an aggregate function
LINE 1: select * from "purchases" group by "purchase_order_id"
^ (SQL: select * from "purchases" group by "purchase_order_id")
There you have it add group by "purchases.id" or restrict the select to only the operates that are needed.
->select("purchase_order_id","purchases.id")
->groupBy("purchases.id") // add if possible
Agreggates for your case should mean something like ->select("sum(po_total)")
If we group by id, we get all results as id is unique, my mistake. You want something like this
DB::table("purchases")->select("purchase_order_id", DB:raw("sum(po_total)"))->groupBy("purchase_order_id")->get();
Rule of thumb is you either select a field with Sum() or have it on the group by
I was trying to get the nearest people from mover_location table using the query as follows :
select * from mover_location where
public.st_dwithin(public.st_geogfromtext('SRID=4326;POINT(11.2565999 75.7711587)'),
last_seen_location_geog, 1060)
Which is not working and give me error like as follows :
ERROR: function _st_expand(public.geography, double precision) does not exist
and i didnt called the st_expand function , How can i resolve this ,Or is there any other
workarounds ? thanks .
My mover_location table structure is as follows ,here last_seen_location_geog is of geography type
UPDATE :-
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
QUERY: SELECT $1 && _ST_Expand($2,$3) AND $2 && _ST_Expand($1,$3) AND _ST_DWithin($1, $2, $3, true)
CONTEXT: SQL function "st_dwithin" during inlining
Add public schema to your search_path:
set search_path to your_schema, public;