I've been looking through the AWS Dynamo DB documentation and the Amazon Dynamo interface and it seems like there's no way to remove a column from a table, outside of deleting the entire table with it's contents and starting over, is that true?
If so, why would Amazon not support this?
Try removing all data from that column, it will automatically remove that column.
Using document client with javascript, we can do this:
const paramsUpdate = {
TableName: tableName,
Key: { HashKey: 'hashKey' },
UpdateExpression: 'remove #c ',
ExpressionAttributeNames: { '#c': 'columnName' }
};
documentClient.update(paramsUpdate, (errUpdate) => {
if (errUpdate) log.error(errUpdate);
});
In here we set UpdateExpression with remove sentence
There is a REMOVE action in the DynamoDB API.
DynamoDB does not have a schema definition, and so there is no such thing as a "column". It also means there is no way to delete all attributes with the same name without iterating over each record.
A solution I recommend is to keep these attributes, and to make your code refer to that same data using a fresh attribute name.
For example, attribute content could become content_v2. It might not look so clean, but it's cheap, quick and your old data would be backed up.
Setting all instances of the column value to null clears the column.
In C#, this method does the trick using the persistence framework:
static void RemoveColumn()
{
var myItems = context.ScanAsync<MyObjectType>(null).GetRemainingAsync().Result;
// Foreach item, update
myItems.ForEach(myObject =>
{
myObject.UnwantedColumn = null;
context.Save(myObject);
});
}
Just remove all the data for that one column. On my end, it automatically refreshed, might have to refresh the page.
Related
I'm currently using AWS Lambda (NodeJS) with AWS QLDB.
The scenario is like this.
I have the first table and its indexes when I deployed the service. So the table and indexes will be created. My problem is that, once I need to add new table and its indexes; it can't create the index because there's existing table.
My workaround to be able to create new table even if there's an existing table in my Ledger is that I'm querying the list of tables I have.
const getTables = async (transactionExecutor: TransactionExecutor) => {
const statement = `SELECT name FROM information_schema.user_tables`;
return await transactionExecutor.execute(statement);
};
Then I have this condition to check if the table is already existing
const tables = JSON.stringify(result.getResultList());
if (
!JSON.parse(tables).some((object): boolean => object.name === process.env.TABLE_NAME)
) {
console.log('TABLE A NOT EXISTING');
await createTable(transactionExecutor, process.env.TABLE_NAME);
}
if (
!JSON.parse(tables).some(
(object): boolean => object.name === process.env.TABLE_NAME_1,
)
) {
console.log('TABLE B NOT EXISTING');
await createTable(transactionExecutor, process.env.TABLE_NAME_1);
}
I don't know how to do it with indexes, I tried using SQL commands in QLDB but it's not working.
I hope you can help me.
Thank you
I'm not quite sure what your question is (the post title and body hint at different things), but I'm going to do my best to answer.
First, QLDB stores data in Ion, not JSON. So, please use the Ion APIs to parse data and not the JSON ones. The reason your code works at all is because Ion is a superset of JSON and the result set doesn't include types that are unknown to JSON. So, for example, if the result set was changed to include an Ion Timestamp, then your code would break.
Next, actually getting a list of tables has first class support in the driver. Simply use driver.getTableNames.
Third, I think you have a question "can I add an index to a non-empty table?". The answer is "no". This is planned functionality and I will update this answer when it is available. UPDATE: Now you can! https://aws.amazon.com/about-aws/whats-new/2020/09/amazon-qldb-launches-index-improvements/
Finally, I think you're also asking if there is a way to list indexes on a table in the same way as you can list tables in a ledger. The answer to that is 'yes'. The documents returned in information_schema.user_tables look like this:
{
tableId:"...",
name:"THE_TABLE_NAME",
indexes:[
{
expr:"[THE_FIELD_BEING_INDEXED]"
}
],
status:"ACTIVE"
}
DynamoDB does not support batch update, it supports batch put only.
But is it possible to batchPut only of item with key does not exist?
In the batchWriteItem, there is the following note:
For example, you cannot specify conditions on individual put and delete requests, and BatchWriteItem does not return deleted items in the response.
Instead, I would recommend using putItem with a conditional expression. Towards the bottom of the putItem documentation there is the following note:
[...] To prevent a new item from replacing an existing item, use a
conditional expression that contains the attribute_not_exists function
with the name of the attribute being used as the partition key for the
table [...]
So make sure to add the following to ConditionExpression (using NodeJS syntax here)
const params = {
Item: {
userId: {
S: "Beyonce",
}
},
ConditionExpression: "attribute_not_exists(userId)"
};
I have table with the following structure
HashKey: Place Name
Attribute: Place Data Class
now i would like to search with Place Name,
Ex: I have below data
Newyork {lat: x.xxxxx, lng: x.xxxxxx}
Newzealand {lat: x.xxxxx, lng: x.xxxxxx}
IndialaPolis {lat: x.xxxxx, lng: x.xxxxxx}
when i searching with keyword new, it should return Newyork and Newzealand, I searched google for this, i found that we can get all records by the HashKey
When doing a Query, you can only have exact matches on the HashKey.
However, there is also the Scan operation, that you can use along with a FilterExpression. Just note that Query and Scan perform and consume capacity differently. See the differences here.
Here are example parameters you could use on a Scan with begins_with:
{
table_name: tableName,
filter_expression: "begins_with(#country, :search)",
expression_attribute_names: {
"#country" => "country"
},
expression_attribute_values: {
":search" => "new"
}
}
This article is a good place to start.
Thank you #mark-b and #bruno-buccolo, as you said it is not possible to Search hashkey field
So i created Elastic Search Indexes for that table manually and updating each time the original record updates
How can I perform a where-in type query using ember-data?
Say I have a list of tags - how can I use the store to query the API to get all relevant records where they have one of the tags present?
Something like this:
return this.store.find('tags', {
name: {
"in": ['tag1', 'tag2', 'tag3']
}
})
There isn't built in support for something like that. And, I don't think its needed.
The result that you are after can be obtained in two steps.
return this.store.find('posts'); // I guess its a blog
and then in your controller you use a computed property
filteredPosts: function('model', function() {
var tags = ['tag1', 'tag2', 'tag3'];
return this.get('model').filter(function(post) {
if ( /* post has one of tags */ ) {
}
return false;
});
});
Update: What if there are tens of thousands of tags?!
Amother option is to send a list of tags as a single argument to the back end. You'll have to do a bit of data processing before sending a request and before querying.
return this.store.find('tags', {
tags: ['tag1', 'tag2', 'tag3'].join(', ')
})
In your API you'll know that the tags argument needs to be converted into an array before querying the DB.
So, this is better because you avoid the very expensive nested loop caused by the use of filter. (expensive !== bad, it has its benefits)
It is a concern to think that there will be tens of thousands of tags, if those are going to be available in your Ember app they'll have a big memory footprint and maybe something much more advanced is needed in terms of app design.
I am creating items on the fly via Sitecore Web Service. So far I can create the items from this function:
AddFromTemplate
And I also tried this link: http://blog.hansmelis.be/2012/05/29/sitecore-web-service-pitfalls/
But I am finding it hard to access the fields. So far here is my code:
public void CreateItemInSitecore(string getDayGuid, Oracle.DataAccess.Client.OracleDataReader reader)
{
if (getDayGuid != null)
{
var sitecoreService = new EverBankCMS.VisualSitecoreService();
var addItem = sitecoreService.AddFromTemplate(getDayGuid, templateIdRTT, "Testing", database, myCred);
var getChildren = sitecoreService.GetChildren(getDayGuid, database, myCred);
for (int i = 0; i < getChildren.ChildNodes.Count; i++)
{
if (getChildren.ChildNodes[i].InnerText.ToString() == "Testing")
{
var getItem = sitecoreService.GetItemFields(getChildren.ChildNodes[i].Attributes[0].Value, "en", "1", true, database, myCred);
string p = getChildren.ChildNodes[i].Attributes[0].Value;
}
}
}
}
So as you can see I am creating an Item and I want to access the Fields for that item.
I thought that GetItemFields will give me some value, but finding it hard to get it. Any clue?
My advice would be to not use the VSS (Visual Sitecore Service), but write your own service specifically for the thing you want it to do.
This way is usually more efficient because you can do exactly the thing you want, directly inside the service, instead of making a lot of calls to the VSS and handle your logic on the clientside.
For me, this has always been a better solution than using the VSS.
I am assuming you are looking to find out what the fields looks like and what the field IDs are.
You can call GetXml with the ID, it returns the item and all the versions and fields set in it, it won't show fields you haven't set.