Grocery CRUD: How to debug Add / Edit errors - sql

I have a N:M relation beetween 'Museum' and 'Category'. Three tables:
Museum: id, name, ...
Category: id, name, ...
Museum_x_Category: museum_id, category_id
And have set a N:M relation with a sentence like:
$crud->set_relation_n_n('Museum Categories', 'Museum_x_Category', 'Category', 'museum_id', 'category_id', 'name', 'category_id' );
I'm getting "An error ocurred on insert" errors when adding, and "An error has occurred on saving." when editing/uploading.
I guess it is due to an SQL error, and i'd like to see the SQL sentences running behind.
Does anyone know how to see it?
PHP: 5.3.5
MySQL: 5.1.14

Solved it. There were two problems:
1.- there was a non-utf8 character in the relation name:
$crud->set_relation_n_n('Categorías', 'Museum_x_Category', 'Category', 'museum_id', 'category_id', 'name', 'category_id' );
now replaced by:
$crud->set_relation_n_n('Categorias', 'Museum_x_Category', 'Category', 'museum_id', 'category_id', 'name' );
(note the í in Categorías, which means Categories in Spanish).
2.- there was a problem with the last parameter ('category_id'). Note that i've removed it. With the parameter included, it was assigning all the museums to the first category, always, whatever category i select.
It works as desired now :)

Related

How to use unnest array with dynamic Postgresql query across two tables

I am relatively new to SQL and having some difficulty understanding how to run a conditional query. For some context, this query is being run with Node/Express using Postgresql.
Situation
If a user selects 'Team A' the query (in the backend) will take the data from one table, while if the user selects 'Team B' it will run the query against a different table. To render the table correctly I need to transpose the data and understand I can achieve this with UNNEST(array[]).
I can run the query successfully with the following code:
SELECT "TeamA" AS "Player",
UNNEST(array['Type1', 'Type2', 'Type2']) AS "Type",
UNNEST(array["Column1", "Column2", "Column3"]) AS "Type2",
UNNEST(array["Column4", "Column5", "Column6"]) AS "Type3",
UNNEST(array["Column7", "Column8", "Column9"]) AS "Type4",
UNNEST(array["Column10", "Column11", "Column12"]) AS "Type5"
FROM sportingdb."TeamAData"
WHERE "TeamA" = '${player}'
However this needs to be dynamic and query a different table if the user selects 'Team A' or 'Team B'.
I have attempted to use the same query with a ternary, however was given a syntax error and am unable to identify where I have gone wrong. I also broke it down as an if else statement as follows:
DO
BEGIN
IF '${TeamA}' = "TeamA" THEN
SELECT "TeamA" AS "Player",
UNNEST(array['Type1', 'Type2', 'Type2']) AS "Type",
UNNEST(array["Column1", "Column2", "Column3"]) AS "Type2",
UNNEST(array["Column4", "Column5", "Column6"]) AS "Type3",
UNNEST(array["Column7", "Column8", "Column9"]) AS "Type4",
UNNEST(array["Column10", "Column11", "Column12"]) AS "Type5"
FROM sportingdb."TeamAData"
WHERE "TeamA" = '${player}'
ELSE
SELECT "TeamB" AS "Player",
UNNEST(array['Type1', 'Type2', 'Type2']) AS "Type",
UNNEST(array["Column1", "Column2", "Column3"]) AS "Type2",
UNNEST(array["Column4", "Column5", "Column6"]) AS "Type3",
UNNEST(array["Column7", "Column8", "Column9"]) AS "Type4",
UNNEST(array["Column10", "Column11", "Column12"]) AS "Type5"
FROM sportingdb."TeamBData"
WHERE "TeamB" = '${player}'
END IF
END
I found this link was somewhat helpful, which I followed to write the above code but arrived with an SQL error [42601]: ERROR: syntax error at or near "BEGIN". I also tried adding the dollar signs as per the example as well as a DECLARE line but this didn't seem to work.
I would truly appreciate any assistance on how I can get this to work. Thanking you in advance!

Prisma PostgreSQL queryRaw error code 42P01 table does not exist

I am trying to run a query that searches items in the Item table by how similar their title and description are to a value, the query is the following:
let items = await prisma.$queryRaw`SELECT * FROM item WHERE SIMILARITY(name, ${search}) > 0.4 OR SIMILARITY(description, ${search}) > 0.4;`
However when the code is run I receive the following error:
error - PrismaClientKnownRequestError:
Invalid `prisma.$queryRaw()` invocation:
Raw query failed. Code: `42P01`. Message: `table "item" does not exist`
code: 'P2010',
clientVersion: '4.3.1',
meta: { code: '42P01', message: 'table "item" does not exist' },
page: '/api/marketplace/search'
}
I have run also the following query:
let tables = await prisma.$queryRaw`SELECT * FROM pg_catalog.pg_tables;`
Which correctly shows that the Item table exists! Where is the error?
After doing some light research, It looks like you possibly need double-quotes. Try
let items = await prisma.$queryRaw`SELECT * FROM "Item" ... blah blah
I say this because PostgreSQL tables names and columns default to lowercase when not double-quoted. If you haven't built much of your db, it may be worth wild to make all the tables and columns lowercase so that you won't have to keep adding double quotes and escaping characters.
References:
PostgreSQL support
Are PostgreSQL columns case sensitive?

How to use a function in select along with all the records in Sequalize?

Here is a Sequalize query below which retrieves a transformed value based on the table column value.
courses.findAll({
attributes: [ [sequelize.fn('to_char', sequelize.col('session_date'), 'Day'), 'days']]
});
The above sequlaize query will return result equal to as followed SQL query.
select to_char(bs.session_date, 'Day') as days from courses bs;
Expected output:
I want the transformed value which is in attributes along with all records like below. I know we can mention all the column names in attributes array but it is a tedious job. Any shortcut similar to asterisk in SQL query.
select to_char(bs.session_date, 'Day') as days,* from courses bs;
I tried the below sequalize query but no luck.
courses.findAll({
attributes: [ [sequelize.fn('to_char', sequelize.col('session_date'), 'Day'), 'days'],'*']
});
The attributes option can be passed an object as well as an array of fields for finer tuning in situations like this. It's briefly addressed in the documentation.
courses.findAll({
attributes: {
include: [
[ sequelize.fn('to_char', sequelize.col('session_date'), 'Day'), 'days' ]
]
}
});
By using include we're adding fields to the courses.* selection. Likewise we can also include an exclude parameter in the attributes object which will remove fields from the courses.* selection.
There is one shortcut to achieve the asterisk kind of selection in Sequalize. Which can be done as follows...
// To get all the column names in an array
let attributes = Object.keys(yourModel.rawAttributes);
courses.findAll({
attributes: [...attributes ,
[sequelize.fn('to_char', sequelize.col('session_date'), 'Day'), 'days']]
});
This is a work around there may be a different option.

How to INSERT a reference to UUID from another table in PostgreSQL?

I'm learning to use Sequelize to use with a PostgreSQL database. All of the following is happening on a dev. environment. This happened while manually trying to insert data into my tables to check if things are setup correctly through Sequelize, check on failing unit tests, etc.
I've made two tables with Sequelize models: User and Publication. Both these tables are generating UUIDv4. I've associated the User hasMany Publications, and Publication belongsTo User (you may reference the extra info).
On my psql shell, I've inserted the following record to my User table (rest of the data cut out for brevity):
| id | firstName | lastName | ..|
|----------------------------------------|------------|-----------|---|
| 8c878e6f-ee13-4a37-a208-7510c2638944 | Aiz | .... |...|
Now I'm trying to insert a record into my Publication table while referencing my newly created user above. Here's what I entered into the shell:
INSERT INTO "Publications"("title", "fileLocation", ..., "userId")VALUES('How to Pasta', 'www.pasta.com', ..., 8c878e6f-ee13-4a37-a208-7510c2638944);
It fails and I receive the following error:
ERROR: syntax error at or near "c878e6f"
LINE 1: ...8c878e6f-ee...
(it points to the second character on the terminal in LINE 1 reference - the 'c').
What's wrong here? Are we supposed to enter UUIDs another way if we want to do it manually in psql? Do we paste the referenced UUID as a string? Is there a correct way I'm missing from my own research?
Some extra info if it helps:
From my models:
Publication.associate = function(models) {
// associations can be defined here
Publication.belongsTo(models.User, {
foreignKey: "userId"
});
};
and
User.associate = function(models) {
// associations can be defined here
User.hasMany(models.Publication, {
foreignKey: "userId",
as: "publications"
});
};
Here's how I've defined userId in Publication:
userId: {
type: DataTypes.UUID,
references: {
model: "User",
key: "id",
as: "userId"
}
}
If it's worth anything, my (primaryKey) id on both models are type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4 (I don't know if this is an issue).
surround your uuid in apostrophes (write it as a string) and pg will convert it to a uuid
Starting and ending your string with {} is optional
Eg
INSERT INTO "Publications"("title", "fileLocation", ..., "userId")VALUES('How to Pasta', 'www.pasta.com', ..., '8c878e6f-ee13-4a37-a208-7510c2638944');
Or
INSERT INTO "Publications"("title", "fileLocation", ..., "userId")VALUES('How to Pasta', 'www.pasta.com', ..., '{8c878e6f-ee13-4a37-a208-7510c2638944}');
Source (I don't do pgsql much so I casted around for another person who wrote some working pgsql. If this doesn't work out for you let me know and I'll remove the answer): PostgreSQL 9.3: How to insert upper case UUID into table

Add AS-Expression to selected columns in getCollection()

As an follow up idea to solve my "sort product collection by sub-category" problem explained in my question sorting collections by subcategory, an attribute and by productname I had the idea to add a AS expression to the selected fields of the collection.
What I want to achieve (SQL-wise) is something like this:
SELECT field1, 'some string' as 'category_name' FROM ...
So I thought I could use the addExpressionFieldToSelect in the method chain to dynamically add the category name string to the products collection.
For that have the following:
// ...
$_products = Mage::getModel('catalog/product')
->getCollection()
->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id = entity_id', null, 'left')
->addAttributeToSelect('*')
->addExpressionFieldToSelect('\'some category name\'', 'AS', 'category_name')
->addAttributeToFilter('status', 1)
->addAttributeToFilter('visibility', 4)
->addAttributeToFilter('is_saleable', array('like' => '1'))
->addAttributeToFilter('category_id', $_subcategory_finset_ids)
->addAttributeToSort('ws_geschmack', 'ASC')
->addAttributeToSort('name', 'ASC');
// ...
But with that I get an error:
Fatal error: Call to undefined method Mage_Catalog_Model_Resource_Product_Collection::addExpressionFieldToSelect() ...
Short explanation: In fact I am not able to sort product collections by sub-category (string) I first query all child categories of a parent category (ordered) and within a loop I query all products of these child categories (down to the deepest level) to get products sublists of each subcategory and sub-sub categories. To fully understand my problem, please refer to my question mentioned above.
It is just a try, I do not know if all this is really working. As a hack for now I just try to come a little closer with that AS expression field holding the category name of the outer loop. I then could merge these collections and would have a final products collection.
If there is a more simple way, please let me know.
Any help is greatly appreciated!!
Update
Instead of using addExpressionFieldToSelect it is possible to use this:
$_products->getSelect()
->columns(
array(
'category_name' => new Zend_Db_Expr(
'some string')
)
);
As stated above in my update, I solved the problem by using:
$_products->getSelect()
->columns(
array(
'category_name' => new Zend_Db_Expr('some string')
)
);
In fact, simple solution!