Finding the origin of Postgres/Sequelize duplicate alias error (code 42712) - sql

I'm using Sequelize to manage by Postgres SQL database in a node.js project. I'm running into namespace errors but can't for the life of me figure out why.
The code that works:
// db variable holds initialized database connection
const link = name => ( {
through: db.define( name, {
amount: Sequelize.FLOAT,
unit: Sequelize.STRING,
dataSource: Sequelize.STRING
} ),
as: name + 's'
} )
// All model variables (Material, Component etc) have model names
// identical to their variable names (bit without capitals)
Material.belongsToMany( Material, link( 'materialchildmaterial' ) )
Component.belongsToMany( Component, link( 'componentchildcomponent' ) )
Input.belongsToMany( Input, link( 'inputchildinput' ) )
Component.belongsToMany( Component, link( 'componentchilddependency' ) )
The moment I add the following things break:
Input.belongsToMany( Component, link( 'componentchildinput' ) )
The error:
{ name: 'SequelizeDatabaseError',
parent:
{ name: 'error',
length: 177,
severity: 'ERROR',
code: '42712',
file: 'parse_relation.c',
line: '420',
routine: 'checkNameSpaceConflicts' },
original:
{ name: 'error',
length: 177,
severity: 'ERROR',
code: '42712',
file: 'parse_relation.c',
line: '420',
routine: 'checkNameSpaceConflicts' } }
From the postgres docs code 42712 stands for 'DUPLICATE ALIAS'.
My confusion: I am using unique names for everything (afaik). When I change the Input <--> Component link's name to 'randomthing' the error does not appear.
I've been stuck at this for a good day now. Any clues appreciated.

Related

Sequelize addIndex on BLOB Field

I'm using v6 of Sequelize with mariaDB. When I try to execute the following in a migrate file:
return queryInterface.addIndex('RVersion', ['terms'], {
indicesType: 'FULLTEXT'
});
I get the following error message:
BLOB/TEXT column 'terms' used in key specification without a key length
What is the correct way to create this index in sequelize?
Use fields option in options instead of the second parameter like this:
return queryInterface.addIndex('RVersion', {
fields: [{
name: 'terms',
length: 255
}],
type: 'FULLTEXT' // this option name is `type`
});

Get Article list by subscription

I am trying to make a filter with which I could get subscription records
Entity 'Subscription'
export class Subscription {
#PrimaryColumn()
id: string;
#Column('uuid')
userId: string;
#Column('uuid')
targetUserId: string;
#CreateDateColumn()
createdAt: Date;
}
Filter
applyFilter(query: QueryArticle, qb: SelectQueryBuilder<Article>, userId?: string) {
if (query.filter) {
switch (query.filter) {
....
case 'subscriptions':
qb.select(
`article.authorId WHERE targetUserId IN (SELECT targetUserId FROM Subscription WHERE userId=${userId})`,
);
break;
}
}
return qb;
}
SQL code
Select * FROM article WHERE authorId=targetUserId IN (SELECT targetUserId FROM Subscription WHERE userId=userId)
Error
syntax error at or near "f5779e5" +3974ms
QueryFailedError: syntax error at or near "f5779e5"
How can I get all the posts of people followed by a person use TypeORM?
Thanks in advance for your answer!
DO NOT DO WHAT YOU ARE DOING. You are risking a SQL Injection. If you really want to do a manual query, you can do manager.query:
const output = manager.query('article."authorId" WHERE "targetUserId" IN (SELECT "targetUserId" FROM Subscription WHERE "userId" = :userId)',
{ userId: userId }
);
Notice the second parameter that contains parameters which is referenced by key with :userId. If you're using template strings for queries, you're probably doing something wrong.
If you want to use the QueryBuilder, then it's going to look a little different (more info on QueryBuilder here)
const output = articleRepo.createQueryBuilder('article')
.select('article.authorId')
.where('article."authorId" IN (SELECT "targetUserId" FROM subscription WHERE "userId" = :userId)',
{ userId: userId }
)
.getRawMany(); // If you remove the .select('article.authorId'), you can use .getMany()

How to select specific fields on FaunaDB Query Language?

I can't find anything about how to do this type of query in FaunaDB. I need to select only specifics fields from a document, not all fields. I can select one field using Select function, like below:
serverClient.query(
q.Map(
q.Paginate(q.Documents(q.Collection('products')), {
size: 12,
}),
q.Lambda('X', q.Select(['data', 'title'], q.Get(q.Var('X'))))
)
)
Forget the selectAll function, it's deprecated.
You can also return an object literal like this:
serverClient.query(
q.Map(
q.Paginate(q.Documents(q.Collection('products')), {
size: 12,
}),
q.Lambda(
'X',
{
title: q.Select(['data', 'title'], q.Get(q.Var('X')),
otherField: q.Select(['data', 'other'], q.Get(q.Var('X'))
}
)
)
)
Also you are missing the end and beginning quotation marks in your question at ['data, title']
One way to achieve this would be to create an index that returns the values required. For example, if using the shell:
CreateIndex({
name: "<name of index>",
source: Collection("products"),
values: [
{ field: ["data", "title"] },
{ field: ["data", "<another field name>"] }
]
})
Then querying that index would return you the fields defined in the values of the index.
Map(
Paginate(
Match(Index("<name of index>"))
),
Lambda("product", Var("product"))
)
Although these examples are to be used in the shell, they can easily be used in code by adding a q. in front of each built-in function.

Datatables - Inline editor only updates host table

I have a simple table using a left join:
Editor::inst( $db, 'enqitem', 'enqitemid')
->fields(
Field::inst( 'salstkitem.salsubid' ),
Field::inst( 'salstkitem.condition1' ),
Field::inst( 'enqitem.cost' )
)
->leftJoin('salstkitem', 'salstkitem.salsubid', '=', 'enqitem.itemid')
->where('enqitem.enqnr',141316)
->debug( true )
->process( $_POST )
->json();
In the editor, I have hidden the primary key of the non-host table:
editor = new $.fn.dataTable.Editor( {
ajax: "datatables.php",
table: "#example",
fields: [{
name: "salstkitem.salsubid",
type: "hidden"
},{
label: "Condition:",
name: "salstkitem.condition1"
},{
label: "Cost:",
name: "enqitem.cost"
}
]
});
I've set it to be editable inline:
$('#example').on( 'click', 'tbody td:not(:first-child)', function (e) {
editor.inline( this, {
onBlur: 'submit'
} );
});
When I edit inline, the cost updates successfully, as it's a member of the host table. However condition1 will not update.
If I select the EDIT button, both fields update successfully.
This issue is purely for inline editing.
Does anyone have any idea why?
The debug suggests it isn't trying to update at all. It is purely a SELECT query.
Allan, the creator of datatables got back to me:
If you are writing to a joined table rather than just the master table you need to have Editor submit the joined table's primary key as well (enqitem.enqitemid in this case I guess). When you are inline editing, by default it will only submit the edited field, but you can use the form-options object to change that:
editor.inline( this, {
onBlur: 'submit',
submit: 'allIfChanged'
} );
Regards,
Allan

mobx-state-tree: How to clone a model that includes references?

I'm trying to clone a model that references another model, but I get: Error: [mobx-state-tree] Failed to resolve reference 'H1qH2j20z' to type 'AnonymousModel' (from node: /usualCustomer)... in the clone. The original resolves okay.
Here are my models:
const Job = types.model({
id: types.optional(types.identifier(types.string), shortid.generate()),
jobNumber: types.optional(types.string, ''),
description: '',
usualCustomer: types.maybe(types.reference(Customer)),
})
const Customer = types.model({
id: types.optional(types.identifier(types.string), shortid.generate()),
name: types.optional(types.string, 'New customer'),
})
This function shows the problem:
editJob = job => {
console.log('Original', job)
var newClone = clone(job)
console.log('Clone', newClone)
}
Did you try also to change the identifier of the node you want to clone ?
i'm not sure if it will work. but when you clone the job node, i think the new created job newJob act as a reference to the cloned job, give it a try anyway :
let jobFromSnap = getSnapshot(job);
let newJob = Job.create({...jobFromSnap, id : "NEW_ID_HERE" }) ;