I have table defined with two column, column 1 is the hash key and column 2 is the range key.
I want to get all items defined with the same hash key (so the range key doesn't matter).
I tried to use the new KeyPair().withHashKey(k). But it will throw exception saying that no RANGE key value present.
Is the only option I have is to do a scan for the table to achieve this?
I think the problem is that you are trying to use the GetItem call, which requires the complete key, and only returns one item. You need to use the Query call, and pass in a KeyExpression that only includes the partition key.
Related
So I wanted to fetch the last item/row of my dynamodb table but i am not finding resources. My primary key is id having series of incremented numbers such as 1,2,3... for each row respectively.
This is my function.
async function readMessage(){
const params = {
TableName: table,
};
return dynamo.getItem(params).promise();
}
I am not sure as to what i should be adding in my params.
DynamoDB has two types of primary keys:
Partition key – A simple primary key, composed of one attribute known as the partition key.
Partition key and sort key – Referred to as a composite primary key, this type of key is composed of two attributes. The first attribute is the partition key, and the second attribute is the sort key.
When fetching an item by partition key, you need to specify the exact partition key. You cannot fetch the max/min partition key.
Instead, you may want to create a sort key with a timestamp (or the ID if it's a sequential number) and use the sort key to fetch the last item.
Check out the AWS docs on Choosing the Right Partition Key for more info.
The proper way to design a table in DynamoDB is based on its expected access patterns; if this is something you need perhaps you should consider using this id as Sort Key instead of Primary Key and then query the table in descending order while also limiting the amount of items to 1.
If instead you don't want to change the schema of your items and you don't care about making at least two operations to do this you have two, not optimal options:
If none of your items ever gets deleted, just make a count first and use that information to know what's the latest item that was written.
Alternatively, if you could consider keeping a "special" record in your DynamoDB table that is basically a count that gets always incremented/written when one of your "other" items gets written. Upon retrieval you first retrieve the value of this special record and use this info to retrieve the actual one.
The combination of the partition key and sort key, makes the primary key of your item in the dynamoDB, so their combination must be unique, otherwise the item will be overwritten.
In almost all my use-cases, I select the primary key as an object attribute, like the brand, an email or a class and then, for the sort key I select the TimeStamp. So in this way, you always know the partition key, we need it to retrieve the values and then you can query your dynamoDB by making some filters by the sort key. For more extensive examples using Python, check the AWS page: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.Python.04.html, where it shows, how you can query your DynamoDB items.
There is also other ways to define the keys in your Dynamo and for that I advise you to check https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-sort-keys.html
I have a DynamoDB table called Message with the following attributes:
message_id: number (partition key)
user_id: number (sort key)
incoming: boolean
subject: string
I want to create a global secondary index with user_id for the partition key, and the combined value of incoming and subject for the sort key.
Global secondary index:
user_id: partition key
incoming#subject: sort key
Do I have to manually cast the incoming attribute to a string (where true becomes "1", and false becomes "0") before combining it with subject? What is the standard way to handle such a scenario?
As far as I know, I don't think that you can have different attributes like incoming#subject only in a global secondary index and separate incoming and subject attributes only in the original table. The attributes in your index will reflect the ones in the table. The difference between the two representations is that they have a different partition key and sort key. So, you can't "combine" incoming#subject just in the index without having this attribute in the table as well.
However, having incoming#subject in both the table and the index would solve your problem since its value would be determined outside of the database (when you write into the table). You should thus be able to "cast" it to whatever you want when you insert or update the data--whether it is true#my_subject_here or 1#another_subject.
Let me know if that works for you!
Question
Having gone through verbose AWS documentations, I need some help to clarify the basic keywords and concept of DynamoDB.
Kindly assist to confirm if these are correct.
Hash key
The key which decides the partition of the item, so it is also called as the 'partition' key.
Primary key
A hash key, or (hash-key, range-key) pair that can identify only 1 item in the table. A (hash-key, range-key) pair is also called 'composite' key.
If the primary key has only hash-key, "hash-key" and "primary-key" can be used interchangeably(but doing so can cause confusions).
Local secondary index
In a simple term, "alternative range key" to be used with the hash-key of the primary key.
Besides the range key in the primary key (hash-key, range-key), we can have additional range keys that can be used with the hash-key of the primary key.
Global secondary index
Alternative (hash-key, range-key) pairs for Query.
KeyConditions
For a query on a table, you can have conditions only on the range key portion on the table/index primary key. The hash key condition must always be equal.
Expression attribute name
Dozens of words cannot be used as its attribute name in DynamoDB table, such as status. It is a way to get around this restriction to be able to use such word by prefixing with '#'. Perhaps a design error of DyanmoDB.
Key condition expression
SQL WHERE like part of Query which needs a hash-key of the primary key. It seems it identifies the one partition to get items, then additionally we can use a range-key to narrow down items.
KeyConditions
For a query on a table/index, you can have conditions only on the table/index primary key attributes. You must always provide the partition key name and value as an EQ condition. You can optionally provide a second condition, referring to the sort(aka range) key.
Filter expression
SQL WHERE like part that can be used for both with Query and Scan but only with non-key attributes.
Filter Expressions for Query
A filter expression cannot contain partition key or sort key attributes. You need to specify those attributes in the key condition expression, not the filter expression.
If used in Query in addition to the key expression, the unmatched items are thrown away.
I'm using dynamo db, I was reading this document Class QueryRequest and says literately:
You can narrow the scope of the query by using comparison operators on
the range key value, or on the index key. You can use the
ScanIndexForward parameter to get results in forward or reverse order,
by range key or by index key.
But, I need know if is possible to sort my data according to another parameter (different to hash or range).
Thanks in advance.
You can only Query a Table of type Hash and Range, or a Local Secondary Index or a Global Secondary Index. You have to create the Table with the indexes, so if you haven't then you cannot query on them.
I need to programatically determine what the primary key field(s) are for a given sqlite table (using sqlite api, not command line).
I can get a list of tables and a list of columns, but only see the column type using the Column_Type() function. Need to know if a given column is the primary key (or part of the primary key if a compound key is used).
Have a look at sqlite3_table_column_metadata:
This routine returns metadata about a specific column of a specific
database table accessible using the database connection handle passed
as the first function argument.