I'm just getting up to speed with BookshelfJS, so I'm probably missing something, but I'm wondering how to get query parameters to be formatted correctly for doing a count. For example, if I want my JS objects to use camelCase, and the database rows to use snake_case, I know I can use the format() and parse() functions on the model like so: http://bookshelfjs.org/#parse-and-format
But how do I get query parameters for a count to be converted from camelCase to snake_case before they're run as queries on the DB?
Example:
const Book = bookshelf.Model.extend({
tableName: 'books',
parse: function(response) {
return _.mapKeys(response, function(value, key) {
return _.camelCase(key);
});
},
format: function(attributes) {
return _.mapKeys(attributes, function(value, key) {
return _.snakeCase(key);
});
}
});
Now let's say the books database table has author_name as a column, but, if this is being used in an API, we want users to query on the authorName parameter.
Doing this converts the query parameters just fine:
Book.forge({authorName: 'Clark'}).fetch()
And it queries the DB on author_name instead of authorName. But the analogous:
Book.forge({authorName: 'Clark'}).count()
doesn't work as expected, because it's not converting authorName to author_name before querying. How do I get bookshelf to use the format() function I wrote to do this?
Related
In my current scenario, a third party will be creating tables dynamically on my DB, and storing the table name as a varchar and column names as jsonb in other table which is defined as an Entity in my NestJS backend.
This is so I can keep track (and query) these tables, since I have no control over its creation.
For this purpose I'd like to use TypeORM's createQueryBuilder instead of using raw queries as its easier for me to play with abstraction.
As far as I know TypeORMs createQueryBuilder needs a defined Entity in the from clause.
Something like this:
return await getManager()
.createQueryBuilder()
.select('*')
.from(MyDefinedModel, 'modelAlias')
.getRawMany();
}
So I'd like to do something like:
const tableName = await getDynamicallyGenetaredTableNames().getFirstOne()
// now tableName points to a string that is a table name, i.e 'table-data-192239'
return await getManager()
.createQueryBuilder()
.select('*')
.from(tableName, 'tableAlias')
.getRawMany();
So passing the table name I point to the right table, but TypeORM (and TS) complains because that tableName is a string, and not an Entity (Class) type
I really don't want to type-cast and start doing nasty things if there is something cleaner to achieve this.
I didn't find any solution in the official docs
Any brilliant ideas out there?
Thanks, y'all
We can pass table name instead of Entity for getRepository.
let tableName = 'user';
let query = getRepository(tableName).createQueryBuilder(tableName);
You can select from a table by its table name without defining an entity before like this:
const res = await manager
.createQueryBuilder()
.select()
.from("tableName", null)
.where("tableName.id = :id", { id: 1 })
.getRawMany();
Be sure that you set the second parameter of the from() explicitly to null.
You could try using a raw query:
import { getManager } from 'typeorm'
const tableName = await getDynamicallyGenetaredTableNames().getFirstOne()
// Use the table name in a raw SQL query
const result = await getManager().query(`SELECT * FROM ${tableName}`)
i have an api endpoint https://countriesnode.herokuapp.com/v1/countries.
Now i am fetching all the countries by
axios.get('https://countriesnode.herokuapp.com/v1/countries')
it returns successfully. Besides I want to fetch single countries with the country code like 'BB' .and i am trying with params and my object is like below
axios.get('https://countriesnode.herokuapp.com/v1/countries',
{
params: {
code: codeId
}
but it returns all the data like above rather than showing a single country with the following code. I also want to extract only the currency and area code. I wanted to try like this, don't know it gonna work or not.
.then(axios.spread((object) => {
console.log('Currency: ', object.data.currency);
console.log('Area code: ', object.data.emojiU);
}));
please someone help me... It took me almose the hole day for this but not able to success.
As per your comment, if you want to get the data of a specific country, you only have to append the country code id to the URL:
const codeId = 'BB';
axios.get(`https://countriesnode.herokuapp.com/v1/countries/${codeId}`)
Would give you the data for Barbados.
If you want to access the currency attribute you can do so with the code:
const codeId = 'BB';
axios.get(`https://countriesnode.herokuapp.com/v1/countries/${codeId}`).then(function(response) {
const currency = response.data.currency;
});
I am using sequelize for migration. here I execute an INSERT query with following options but its didnot return created records:
const res = oldUsers.map(u => sequelize.query(
`INSERT INTO ${LP_LOCATIONS_TABLE} (name, address, city)
VALUES (
'${u.email}', '${u.address}', '${u.city}');`,
{ type: DataTypes.QueryTypes.INSERT, raw: true },
))
the output is an array of array like below:
[ [[0],[1]] ]
i expect to get created recorders. specially PK. how can I fix it?
I forgot to put RETURNING * at the end of the raw SQL query.
From the doc, you may have to specify the option returning:true to make this happen. I use mySql, so can't test (the returning option is only for postgres).
I want to obtain all the fields of a schema in mongoose. Now I am using the following code:
let Client = LisaClient.model('Client', ClientSchema)
let query = Client.findOne({ 'userclient': userclient })
query.select('clientname clientdocument client_id password userclient')
let result = yield query.exec()
But I want all the fields no matter if they are empty. As always, in advance thank you
I'm not sure if you want all fields in a SQL-like way, or if you want them all in a proper MongoDB way.
If you want them in the proper MongoDB way, then just remove the query.select line. That line is saying to only return the fields listed in it.
If you meant in a SQL-like way, MongoDB doesn't work like that. Each document only has the fields you put in when it was inserted. If when you inserted the document, you only gave it certain fields, that document will only have those fields, even if other documents in other collections have different fields.
To determine all available fields in the collection, you'd have to find all the documents, loop through them all and build an object with all the different keys you find.
If you need each document returned to always have the fields that you specify in your select, you'll just have to transform your object once it's returned.
const fields = ['clientname', 'clientdocument', 'client_id', 'password', 'userclient'];
let Client = LisaClient.model('Client', ClientSchema)
let query = Client.findOne({ 'userclient': userclient })
query.select(fields.join(' '))
let result = yield query.exec()
fields.forEach(field => result[field] = result[field]);
That forEach loop will set all the fields you want to either the value in the result (if it was there) or to undefined if it wasn't.
MongoDB is schemaless and does not have tables, each collection can have different types of items.Usually the objects are somehow related or have a common base type.
Retrive invidual records using
db.collectionName.findOne() or db.collectionName.find().pretty()
To get all key names you need to MapReduce
mapReduceKeys = db.runCommand({
"mapreduce": "collection_name",
"map": function() {
for (var key in this) {
emit(key, null);
}
},
"reduce": function(key, stuff) {
return null;
},
"out": "collection_name" + "_keys"
})
Then run distinct on the resulting collection so as to find all the keys
db[mapReduceKeys.result].distinct("_id") //["foo", "bar", "baz", "_id", ...]
See the sample code below - in this case, the objectId for the record I am trying to retrieve is known.
My question is, if I don't know the Parse.com objectId, how would I implement the code below?
var Artwork = Parse.Object.extend("Artwork");
var query = new Parse.Query(Artwork);
query.get(objectId, {
success: function(artwork) {
// The object was retrieved successfully.
// do something with it
},
error: function(object, error) {
// The object was not retrieved successfully.
// warn the user
}
});
Query.get() is used when you already know the Parse object id.
Otherwise, one can use query.find() to get objects based on the query parameters.
Sure, you can use Parse Query to search for objects based on their properties.
The thing that wasn't clear to me in the documentation is that once you get the object in the query, you would need to do:
With Query (can return multiple objects):
artwork[0].get('someField');
With 'first' or 'get':
artwork.get('someField');
You cannot do something like artwork.someField like I assumed you would