Converting a text string to a Google BigQuery TableSchema - google-apps-script

I've been trying, and failing, to generate a Google BigQuery table using a schema that I build from text.
I have no problem defining the schema in script like this:
var fl = {fields: [{name: 'issue_id', type: 'STRING'},.....}
then assigning it as schema: fl
What I want to do is use an array as input to the field list (e.g. name, type) and dynamically build this list into a table schema. I can do this in text (simple string building) but I can't use a text string as a schema - it appears as a null.
There's probably a wildly simple solution but I've not found it yet. It needs to avoid any add-ons if at all possible.
Specific code information
This is the table definition, which requires a schema.
var table = {
tableReference: {
projectId: projectId,
datasetId: datasetId,
tableId: tableId
},
schema: fl
};
If I define fl as below, I don't have a problem. I'm using the expected syntax and it all works.
var fl = {fields: [{name: 'issue_id', type: 'STRING'},{name: 'internal_issue_id', type: 'STRING'}] };
However, if I define fl as below (fs is an array and I'm concatenating text from this array), I end up with fl as a string, which doesn't work here.
var fl = "{fields: ["
while (countRow<numRows) {
fl = fieldList + "{name: '" + fs[countRow][0] + "', type: '" + fs[countRow][1] + "'},";
countRow=countRow+1
}
fl = fl.substring(0,fl.length-1) + "] }"
The string looks exactly like the originally defined variable, but of course is a string so I didn't really expect it to work without some sort of conversion - just like a date string usually needs conversion to be used in date calculations. Currently it appears as a null to the table definition.
I'm sure I'm not the first person to want to do this, and hoping there's a simple solution.

Related

Azure tables unable to store flattened JSON

I am using the npm flat package, and arrays/objects are flattened, but object/array keys are surrounded by '' , like in 'task_status.0.data' using the object below.
These specific fields do not get stored into AzureTables - other fields go through, but these are silently ignored. How would I fix this?
var obj1 = {
"studentId": "abc",
"task_status": [
{
"status":"Current",
"date":516760078
},
{
"status":"Late",
"date":1516414446
}
],
"student_plan": "n"
}
Here is how I am using it - simplified code example: Again, it successfully gets written to the table, but does not write the properties that were flattened (see further below):
var flatten = require('flat')
newObj1 = flatten(obj1);
var entGen = azure.TableUtilities.entityGenerator;
newObj1.PartitionKey = entGen.String(uniqueIDFromMyDB);
newObj1.RowKey = entGen.String(uniqueStudentId);
tableService.insertEntity(myTableName, newObj1, myCallbackFunc);
In the above example, the flattened object would look like:
var obj1 = {
studentId: "abc",
'task_status.0.status': 'Current',
'task_status.0.date': 516760078,
'task_status.1.status': 'Late',
'task_status.1.date': 516760078,
student_plan: "n"
}
Then I would add PartitionKey and RowKey.
all the task_status fields would silently fail to be inserted.
EDIT: This does not have anything to do with the actual flattening process - I just checked a perfectly good JSON object, with keys that had 'x.y.z' in it, i.e. AzureTables doesn't seem to accept these column names....which almost completely destroys the value proposition of storing schema-less data, without significant rework.
. in column name is not supported. You can use a custom delimiter to flatten your objects instead.
For example:
newObj1 = flatten(obj1, {delimiter: '__'});

how to read an attribute name in json in google script

I have the following object structure and for each record I need to display the attribute name and its value. for the following example, I need to display "Name " = xxx. The attribute name can be different for each json response. These are field names of a table so I cann't use hard coded names.
How do I read the attribute value?
I tried var propname = DataInObj.DataSet[0].Record[0].properties[1] but it didn't work. Pls help
object
REcord
+attributes
-0
Name xxx
Amount 100
+attributes
-1
Name yyy
Amount 200
See this other post: Iterate over an object in Google Apps script
Code goes like this:
var dict = { "foo": "a", "bar": "b" };
function showProperties(){
var keys = [];
for(var k in dict) keys.push(k+':'+dict[k]);
Logger.log("total " + keys.length + "\n" + keys.join('\n'));
}

Insert geometry values in mysql using node.js

I am using https://github.com/felixge/node-mysql module with node.js.
Mysql table has a field of type POINT. The module requires to send array of arrays to insert bulk records. But It doesn't seem to have option to specify data type.
So naturally, the following gets enclosed in quotes
var loc = "GeomFromText('POINT(" + lat + "," + lon + ")')";
Has anybody tried this? How can I convince the query builder to treat this as an sql function?
Or do I have to make my own query builder?
There is a pull request from kevinhikaruevans that does it. You can do something like that to convert objects to points:
if (typeof val === 'object') {
if(val.hasOwnProperty('lat') && val.hasOwnProperty('long')) {
return 'POINT(' + [val.lat, val.long].map(parseFloat).join(',') + ')';
}
}
Supposing you have a table mytable with only the field point of type POINT, you would insert them like this:
var points = [
[{ lat: 1, long: 4}],
[{ lat: 23, long: -8.345}]
];
var query = connection.query('INSERT INTO mytable(point) VALUES ?', [points], your_callback_func);
console.log("Query: " + query.sql);
This will generate a query similar to:
INSERT INTO mytable(point)
VALUES (POINT(1,4)), (POINT(23,-8.345))
This would convert any object with both lat and long fields to a MySQL point. If this is not an intended behavior, you could create a Point class and use it instead of plain objects, and in lib/protocol/SqlString.js check if the value is an instance of Point.
Try constructing a query to handle POINT() and batch where site is an object with properties and values shown below. This approach works for me.
pool.query('INSERT INTO table SET geometryField = POINT(?,?), ?',[coords.lat,coords.lng,site], function(err, response) {
{ sitename: 'A Site',
customer: 'A Customer',
country: 'AL',
timezone: 'America/Los_Angeles',
address1: '123 My Street',
city: 'MyCity',
state: 'WA',
postalcode: '98110'}

How to map a data to a segment if the data is not in a collection in Kony Studio?

I am using Kony Studio 5.5 for cross platform development. I retrieve data by using a JSON service. I want to print my data in a segment, but I can't map some of it because it is not in a collection.
"chartStat": " CHART NOT PREPARED ",
"passengers": [{
"trainBookingBerth": "RAC9 , 8,GN ",
"trainCurrentStatus": " CNF ",
"trainPassenger": "Passenger 1"
}],
"trainBoard": "Kovilpatti",
"trainBoardCode": "CVP",
"trainDest": "Chennai Egmore",
In the above payload I can map passengers to the segment but I also want to map trainBoard, trainBoardCode and trainDest to it.
If you are using the Kony service editor, parse the output according to your requirement. By parsing the result one can isolate the required parameter -i.e.: Filter the result returned from service- that are only required at the client side and in a format that we can specify.
If you have three labels in the segment and you want to show the passengers details return by the service, please follow these steps:
Parse your JSON data, while mentioning the id in the service editor, please keep in mind to use the id of the children widgets of the segment as the id for output parameter.
After parsing the you must get a collection which is similar as following
[
{ "labelOneId": "RAC1 , 8,GN ", "labelTwoId": " CNF 1", "labelThreeId": "Passenger 1" },
{ "labelOneId": "RAC2 , 8,GN ", "labelTwoId": " CNF 2", "labelThreeId": "Passenger 2" },
{ "labelOneId": "RAC3 , 8,GN ", "labelTwoId": " CNF 3", "labelThreeId": "Passenger 3" },
{ "labelOneId": "RAC3 , 8,GN ", "labelTwoId": " CNF 4", "labelThreeId": "Passenger 4" }
]
Where the labelOneId, labelTwoId and labelThreeId will be the ids used for children of the segment where the data need to be displayed.
After this use the set data method of the Kony.ui.segment widget to set the data.
Note: If you did not use the id of the children widget then you will have to format the data using a "for" loop iterator.
Extracting the value from the sample value provided in your question:
var jsonReturned={
"chartStat": " CHART NOT PREPARED ",
"passengers": [{
"trainBookingBerth": "RAC9 , 8,GN ",
"trainCurrentStatus": " CNF ",
"trainPassenger": "Passenger 1"
}],
"trainBoard": "Kovilpatti",
"trainBoardCode": "CVP",
"trainDest": "Chennai Egmore"
};
var oneVal = jsonReturned["passengers"]["0"]["trainBookingBerth"];
var twoVal = jsonReturned["passengers"]["0"]["trainCurrentStatus"];
var threeVal = jsonReturned["passengers"]["0"]["trainPassenger"];
var fourVal = jsonReturned["trainBoard"];
var fiveVal = jsonReturned["trainDest"];
var dataForSegment = [{
"labelOneId": oneVal,
"labelTwoId": twoVal,
"labelThreeId": threeVal,
"lableFourId": fourVal,
"labelFiveId": fiveVal
}];
Try setting this in the as the dataForSegment as segment data. If you want to add any additional value you have to similarly extract the data from the JSON object and form a collection suitable for your segment.
This question was asked a very long time ago, but for anyone wondering how to do this, you can use the addDataAt and setDataAt methods you can use to respectively insert or replace a single row of data at a specified position in a Segment.
From Kony's Widget Programmer's Guide about the addDataAt method:
Allows you to add one row of data at a given index or within a section.
addDataAt(data, rowIndex, sectionIndex)
and about the setDataAt method:
Allows you to set data or modify an existing data of a row or within a section.
setDataAt(data, rowIndex, sectionIndex)
I hope this helps others in the future.
You need to follow this structure to put data in Segment...
var data=[
[{lblHeading:"Section1"},[{samplelabel:"1"},{samplelabel:"1"},{samplelabel:"1"},{samplelabel:"1"}]],
[{lblHeading:"Section2"},[{samplelabel:"1"},{samplelabel:"1"},{samplelabel:"1"},{samplelabel:"1"}]],
[{lblHeading:"Section3"},[{samplelabel:"1"},{samplelabel:"1"},{samplelabel:"1"},{samplelabel:"1"}]],
[{lblHeading:"Section34"},[{samplelabel:"1"},{samplelabel:"1"},{samplelabel:"1"},{samplelabel:"1"}]]
];
this.view.segmentList.setData(data);

OpenERP Function Many2One with two values (like Value1 | Value2)

Since Many2one field only displays one field, I thought about wrote a function to display in Many2one two fields, like this way:
def get_services(self, cr, uid, ids, context=None):
values = cr.execute("""SELECT name, entity
FROM services WHERE id = 3""")
values.fetchall()
for value__ in values:
if value__:
return {'value': {'service_id': value__[0] + " | " + value__[1]},} # Example: "Service 1 | Google"
First of all, is it possible? Is there any module which does this? So I could see it.
Then, I call the function this way:
_columns = {
'service_id':fields.function(get_services, type = 'many2one', obj = 'services_getservices_function', method = True, string = 'Service'),
I'm not getting any error, but the field doesn't display on the screen.
What you need is overwriting name_get on service model.
see https://doc.openerp.com/trunk/server/api_models/#openerp.osv.orm.BaseModel.name_get
Solved.
I created another field which would contain the name plus the entity.
'name_plus_entity':fields.char('All', size = 300),
Then I created a function "onchange", so whenever the field 'name' OR the field 'entity' was changed, the field 'name_plus_entity' would get: 'name' + " | " + entity.
Also, I hide the field 'name_plus_entity' in the form XML.