Sequelize Many to Many search using OR - javascript

The main idea for my code is to create a search field which I have two many to many fields, and I want to bind the search for the many to many table
I want to select the modelos.nome_modelo_produto field that is inside the table modelos, but never works, because the sequelize dont recognizes the field, even after I mentioned the relationship between the tables:
Modelo.belongsToMany(Produto, {through: 'ProdutosModelos'});
Produto.belongsToMany(Modelo, {through: 'ProdutosModelos'});
And the idea for the search is this...
Table.findAll({
where: {
[Db.Sequelize.Op.or]: [
{'nome_produto': Db.sequelize.where(Db.sequelize.fn('LOWER', Db.sequelize.col('nome_produto')), 'LIKE', '%' + req.query.search + '%')},
{'$modelos.nome_modelo_produto$': Db.sequelize.where(Db.sequelize.fn('LOWER',Db.sequelize.col('$modelos.nome_modelo_produto$')), 'LIKE', '%' + req.query.search + '%')}
]
}
})
But don't works...
Can someone help-me or give-me a way to proceed ?

If anyone have this error, I've checked that when you're using limit or offset tags inside your where there's a annoying error that I could'n solve.
So the tip that I have is to remove the offset and limit, and also rename your table columns to find only by the name, for example, if you have the field tags in the table things, you can rename the tags field to things_tags, if it is a relational field, and when you set the field inside where you can only insert the field name without the table name.

Related

is there any way to select all the fields data from the table except one field data using nodejs

I want to fetch all the fields data but don't want to specify the fields name and don't want to create a view.
I have tried
WITH orderschema as
(SELECT array_to_string(ARRAY(SELECT c.column_name
FROM information_schema.columns As c
WHERE table_name = 'orders'
AND c.column_name NOT IN('Quantity')
), ','))
SELECT * from orderschema
but this is returning the schema fields name as a single string and i can't use this single string to get all the fields from the orders table.
is there any way to exclude the field directly in psql?
Generally speaking no such way exists.
But - if you plan on converting data to JSON in Pg (which you shouldn't for performance reasons, but you might if you really, really want to), you could just delete the column from json.
The best way, though, is to write query that lists only the columns you need.

Sequelize: Selecting distinct field values from multiple columns

I'm using sequelize and mysql2 and need to select all the distinct values from multiple columns.
For example I've a 'Title' and a 'Location' column.
At the moment this:
Job.findAll({
attributes: [
[Sequelize.fn('DISTINCT', Sequelize.col('title')), 'title']
]
})
works, returning all the job titles that are distinct. But if I add a second line for the location column I get a syntax error
Job.findAll({
attributes: [
[Sequelize.fn('DISTINCT', Sequelize.col('title')), 'title'],
[Sequelize.fn('DISTINCT', Sequelize.col('location')), 'location']
]
})
It feels like it should work, from what I've read in the docs at least - but I'm not exactly experienced or confident with sequelize, so any help would be appreciated.
Thanks
I haven't yet found a way to do this less-hackily, but you can exploit the fact that DISTINCT isn't really a function, but a statement and always operates on the entirety of the selected column set:
Job.findAll({
attributes: [
[Sequelize.fn('DISTINCT', Sequelize.col('title')), 'title'],
'location'
]
})
would generate SQL similar to
SELECT DISTINCT(`title`) AS `title`, `location` FROM `Jobs`;
but since DISTINCT is not a function, this is really the same as
SELECT DISTINCT (`title`) AS `title`, `location` FROM `Jobs`;
which does do what you want because parenthesis around column names are optional, that query up there would be the same as
SELECT DISTINCT `title`, `location` FROM `Jobs`;
Source: https://dzone.com/articles/sql-distinct-is-not-a-function (the article also talks about the DISTINCT ON PostgreSQL extension, if someone happens to need that too)
Please note that this feels very hacky and sort of fragile and could/might break if Sequelize ever decides to change the way functions are applied when generating the SQL, but it works in the version of Sequelize I use (5.22.3).

BookshelfJS belongsToMany doesn't return duplicates

I have two tables that are have the relationship belongsToMany. The pivot table also contains a column called state that could have 3 different values. Say my tables are Table1 and Table2.
There can be multiple entries for the same Table1-Table2 relation with different states.
I want to get all the pivot entries for Table1 including any multiple entries for the same Table2.
Unfortunately, the code
return this.belongsToMany(Table2, 'pivot_table1_table2').withPivot(['state'])
only returns the first entry for each Table2.
Help is appreciated.
That's how bookshelf works! It's part of the feature: remove the dupes. I found a workaround; explicitly select an attribute from the junction table that's unique. If you don't have one, create a model for the junction table. That's sadly the only solution then.
UPDATE:
Perhaps something like that. routes.code is unique in my case and it is part of the junction table. If this won't do the trick, create a model for the junction table and you're set (this is probably more preferred).
new Station().where({
id: req.params.id
}).fetch({
withRelated: [{
'routes': function(qb) {
qb.select('routes.id', 'routes.code');
}
}]
}).then(function(result) {
res.json(result.toJSON());
});

Knex.js insert from select

I'm trying to generate a query like the following via Knex.js:
INSERT INTO table ("column1", "column2")
SELECT "someVal", 12345
WHERE NOT EXISTS (
SELECT 1
FROM table
WHERE "column2" = 12345
)
Basically, I want to insert values only if a particular value does not already exist. But Knex.js doesn't seem to know how to do this; if I call knex.insert() (with no values), it generates an "insert default values" query.
I tried the following:
pg.insert()
.into(tableName)
.select(_.values(data))
.whereNotExists(
pg.select(1)
.from(tableName)
.where(blah)
);
but that still just gives me the default values thing. I tried adding a .columns(Object.keys(data)) in hopes that insert() would honor that, but no luck.
Is it possible to generate the query I want with knex, or will I just have to build up a raw query, without Knex.js methods?
I believe the select needs to be passed into the insert:
pg.insert(knex.select().from("tableNameToSelectDataFrom")).into("tableToInsertInto");
Also in order to select constant values or expressions you'll need to use a knex.raw expression in the select:
knex.select(knex.raw("'someVal',12345")).from("tableName")
This is my first post and I didn't test your specific example but I've done similar things like what you're asking using the above techniques.
The most comprehensive answer I've found (with explicit column names for INSERT, and custom values in the SELECT-statement) is here:
https://github.com/knex/knex/issues/1056#issuecomment-156535234
by Chris Broome
here is a copy of that solution:
const query = knex
// this part generates this part of the
// query: INSERT "tablename" ("field1", "field2" ..)
.into(knex.raw('?? (??, ??)', ['tableOrders', 'field_user_id', 'email_field']))
// and here is the second part of the SQL with "SELECT"
.insert(function() {
this
.select(
'user_id', // select from column without alias
knex.raw('? AS ??', ['jdoe#gmail.com', 'email']), // select static value with alias
)
.from('users AS u')
.where('u.username', 'jdoe')
});
console.log(query.toString());
and the SQL-output:
insert into "orders" ("user_id", "email")
select "user_id", 'jdoe#gmail.com' AS "email"
from "users" as "u"
where "u"."username" = 'jdoe'
another one approach (by Knex developer): https://github.com/knex/knex/commit/e74f43cfe57ab27b02250948f8706d16c5d821b8#diff-cb48f4af7c014ca6a7a2008c9d280573R608 - also with knex.raw
I've managed to make it work in my project and it doesn't look all that bad!
.knex
.into(knex.raw('USER_ROLES (ORG_ID, USER_ID, ROLE_ID, ROLE_SOURCE, ROLE_COMPETENCE_ID)'))
.insert(builder => {
builder
.select([
1,
'CU.USER_ID',
'CR.ROLE_ID',
knex.raw(`'${ROLES.SOURCE_COMPETENCE}'`),
competenceId,
])
.from('COMPETENCE_USERS as CU')
.innerJoin('COMPETENCE_ROLES as CR', 'CU.COMPETENCE_ID', 'CR.COMPETENCE_ID')
.where('CU.COMPETENCE_ID', competenceId)
.where('CR.COMPETENCE_ID', competenceId);
Note that this doesn't seem to work properly with the returning clause on MSSQL (it's just being ignored by Knex) at the moment.

Insert row if not exists otherwise update sqlite - JavaScript

I know there have been a lot of questions on this in the past, but I seem to be unable to utilise those answers. I have tried, but they don't seem to work.
I have a table which stores two user inputted values: name and email. When they enter their name and e-mail, it gets stored into a single row of my table.
I want to be able to update this same row with a different name and email if the user types some other values, or insert these values if there weren't any previous values.
My code is here:
db.transaction(function(transaction) {
transaction.executeSql('INSERT INTO Details(name,email)\
VALUES(?,?)',[$('#entername').val(), $('#enteremail').val()],
nullHandler,errorHandler);
});
and the table creation is here if needed:
db.transaction(function(tx){
tx.executeSql( 'CREATE TABLE IF NOT EXISTS Details(Id INTEGER NOT\
NULL PRIMARY KEY,name,email)',
[],nullHandler,errorHandler);
},errorHandler,successCallBack);
I have tried using INSERT OR REPLACE, but this just creates a new row with new details and leaves the previous row there with the old details. Are there any efficient options relevant to my case? Thanks
Finally got it to work. I had to do this:
db.transaction(function(transaction) {
transaction.executeSql('INSERT OR REPLACE INTO Details(id,name,email)\
VALUES(1,?,?)',[$('#entername').val(), $('#enteremail').val()],
nullHandler,errorHandler);
});
where id is the row id. This replaces the first row with whatever else you type for name and email if it doesn't already exist

Categories

Resources