How can I find the last insert ID with Node.js and Postgresql? - node.js

When issuing an "insert" statement to postgres, how can I get the ID of the row last inserted in the DB?
I tried "pg", "pg-native", "pg-connection", and a bunch of other packages. For each package, I tried the sync and async method. I read the thing that pretends to be package documentation. I checked the source code for the packages. For the life of me I can't figure this out, and I can't believe that I'm the only person to face this issue.
Any insight would be greatly appreciated.

The key here is using RETURNING id in your INSERT query.
The pg wiki has an example that shows how this is done.
// Let's pretend we have a user table with the 'id' as the auto-incrementing primary key
var queryText = 'INSERT INTO users(password_hash, email) VALUES($1, $2) RETURNING id'
client.query(queryText, ['841l14yah', 'test#te.st'], function(err, result) {
if (err) //handle error
else {
var newlyCreatedUserId = result.rows[0].id;
}
});
or with async/await:
const result = await client.query(queryText, ['841l14yah', 'test#te.st']);
const newlyCreatedUserId = result.rows[0].id;

Related

Azure stored procedure in Azure portal not working although SQL query works

The following stored procedure failed to produce any result even though the SQL query used in it produced results when tested on the Azure portal.
function checktemp() {
var context = getContext();
var container = context.getCollection();
var response = context.getResponse();
let query = `SELECT DISTINCT {"Elevator": t.connectiondeviceid,
"Vibration": t["vibration"],
"Temperature": t["temperature"]}
FROM t
WHERE t["temperature"] > 75
AND t.EventEnqueuedUtcTime > "2019-08-03T20:30:51.905Z"
ORDER BY t["temperature"] DESC`
// Query documents and take 1st item.
var isAccepted = container.queryDocuments(
container.getSelfLink(), query,
function (err, feed, options) {
if (err) throw err;
// Check the feed and if empty, set the body to 'no docs found',
// else take 1st element from feed
if (!feed || !feed.length) {
response.setBody('no docs found');
}
else {
var body = { moststrain: feed[0] };
response.setBody(JSON.stringify(body));
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
I expect to have items returned, but I always get 'no docs found'. My partition key is /ConnectionDeviceId.
Tested your sample document with your stored procedure code,it works for me.Your SP structure should be fine.
Some mistake with the spell of property(ConnectionDeviceId) you provide,it should be ConnectionDeviceId in sql:t.ConnectionDeviceId.
To solve such issue like something works in the portal, no results in SP, i suggest you removing query statements partially step by step to locate which part of SQL causes no results.
Anyway,the issue is related to partition key. When you query data in the portal, it scans all the partitions. However,if you execute SP,it only scans specific partition.
Since the data is partitioned on 'connectiondeviceid', I was supposed to provide a value of it during execution of the stored procedure.

How do I retrieve anything from cloud datastore in node?

I'm trying to access data that I have stored in datastore (in datastore mode). For some reason, I can't access any data it seems.
Things I've tried.
Access using a key
const datastore = new Datastore({projectId: '...'});
const key = datastore.key([<kind>, <id>]);
return datastore.get(key, (err, entity, x) => {
console.log("yolo", err, entity, x);
return entity;
});
Using a query
const query =
datastore.createQuery(<kind>);
return datastore.runQuery(query, (err, e, nq) => {
console.log(err, e, nq);
return e;
});
Both of the above yields no result. I am 100% sure I have typed the kind correctly.
So this was a stupid mistake on my end, but I keep the question in case someone else does the same mistake.
What I did when I created the entry in datastore was that I put it in a namespace, but then I didn't provide the namespace when I queried for it. Just providing the namespace and I was all good.

How to delete on based of subkey using hset in redis in node js app

I am trying to use redis in my nodejs application. I am able to save and retrieve value perfectly. I am using hash which allows me to have single unique key as well sub-keys. Here offer id is my sub key and offer is key.
I am saving offer like below
let offer = {
offerId: req.query.id,
offerName: req.query.offerName,
offerVendor: req.query.offerVendor
}
client.hset('offer', offer.offerId, JSON.stringify(offer), redis.print);
and retrieving value like below
try {
console.log('ping response:', await client.ping());
const offerId = req.query.id;
client.hget('offer', offerId, function(err, reply){
let offer = JSON.parse(reply);
res.send(offer);
});
} catch(err) {
console.log('ping error:', err);
}
I want to delete offer based on id as like saving or getting on based of id. I have gone through documentation https://github.com/NodeRedis/node_redis#usage-example but didn't find there.
What is the way to do delete offer based on id ?
If you already have the offer id, you can delete it from the offer hash using the hdel command. Your code would look something like:
client.hdel('offer', id)
The result from the call will be an integer count of the number of keys deleted. If you don't know the client id, you can look for it using the hscan command.

Redis: How to save (and read) Key-Value pairs at once by namespace/rule?

I want to utilize Redis for saving and reading a dynamic list of users.
Essentially, Redis is Key-Value pair storage. How can I read all the saved users at once? (for example, creating a namespace "users/user_id")
And since I am a Redis beginner,
Do you think the use of Redis in the above case is proper/efficient?
Thanks.
When using key/values for storing objects you should create a domain specific key by combining the domain name plus the unique id. For example, a user object that might look like this:
// typical user data model
var User = function(params) {
if (!params) params = {};
this.id = params.id;
this.username = params.username;
this.email = params.email;
// other stuff...
};
Then domain key could be created like this:
var createUserDomainKey = function(id) {
return 'User:' + id;
};
If the id was 'e9f6671440e111e49f14-77817cb77f36' the key would be this:
User:e9f6671440e111e49f14-77817cb77f36
Since redis will store string values, you need to serialize, probably with json so to save the user object. Assuming a valid use object would would do something like this:
var client = redis.createClient(),
key = createUserDomainKey( user.id ),
json = JSON.stringify( user ) ;
client.set( key, json, function(err, result) {
if (err) throw err; // do something here...
// result is 'OK'
});
For simple fire-hose queries returning all users, you can do this:
var client = redis.createClient();
client.keys( createUserDomainKey( '*' ), function(err, keys) {
if (err) throw err; // do something here
// keys contains all the keys matching 'User:*'
});
Note that the redis folks discourage the use of 'keys' for production, so a better approach is to build your own index using sorted-set, but if your user list is limited to a few hundred, there is no problem.
And since it returns a list of keys, you need to loop through and get each user then parse the json string to recover the real object. Assuming a populated list of keys, you could do something like this:
var client = redis.getClient(),
users = [];
var loopCallback = function(err, value) {
if (!err && value) {
// parse and add the user model to the list
users.push( JSON.parse( value ) );
}
// pull the next key, if available
var key = keys.pop();
if (key) {
client.get( key, loopCallback );
} else {
// list is complete so return users, probably through a callback;
}
}
// start the loop
loopCallback();
This is a good general purpose solution, but there are others that use sorted sets that are move efficient when you want access to the entire list with each access. This solution gives you the ability to get a single user object when you know the ID.
I hope this helps.
ps: a full implementation with unit tests of this can be found in the AbstractBaseDao module of this project.

DocumentDB: Delete a document by ID

I'm using a new database from Microsoft called DocumentDB. Now I want to delete a document by ID, but I cannot figure out, how to do this. Delete operation in DocumentDB requires self-links and they are different from my own ids.
using (var client = new DocumentClient(EndPoint, AuthKey))
{
await client.DeleteDocumentAsync("**self-link here**");
}
I can execute an additional query to find the self-link and then pass it, but this will require two operations instead one and that is what I'd like to avoid. Is there a better way to remove an entry by ID without using queries or stored procedures?
* UPDATE * This feature has now been implemented
* ORIGINAL ANSWER *
Not today, no. You can head to http://feedback.azure.com/forums/263030-documentdb and vote for the feature there.
Here is how I am deleting document
{
var docUri = UriFactory.CreateDocumentUri(_documentDataBaseId, _documentCollectionId, docId);
await _documentClient.DeleteDocumentAsync(docUri);
}
This features has now been implement (as of the 8/2015 - https://feedback.azure.com/forums/263030-documentdb/suggestions/6333050-it-should-be-possible-to-remove-a-document-by-id
as there's no solution for this case I'd recommend to retrieve all the documents in the existing collection to get access to the SelfLink and _rid values.
I just started a mini wrapper to get access to DocumentDB in Universal Apps and hopefully CrossPlatform using Xamarin: https://github.com/JorgeCupi/documentDB-Win10UAP-wrapper feel free to give me any feedback, participate or request some needed methods.
I have tried this code in nodejs to deletebyId and it works for me.
deleteDocumentById: function(params, callback) {
var self = this,
query= params.query,
collection = params.collection;
client.queryDocuments(collection._self, query, function(err, docs) {
if (err) {
return callback(err);
}
client.deleteDocument(docs[0]._self, docs[0], function(err, success) {
if (err) {
return callback(err);
}
callback(null, success);
});
});
}
I was continuously receiving this error: Microsoft.Azure.Documents.DocumentClientException:
Entity with the specified id does not exist in the system.,
The main trick of deleting is PartionKey id. You suppose inside PartionKey provide id
like in the code example.
I have tried many ways, but I was always receiving different errors...Only this solution worked for me.
await client.DeleteDocumentAsync(input[0].SelfLink,
new RequestOptions
{
PartitionKey = new PartitionKey(input[0].Id)
});
Hope this helps :)

Resources