Question: This is my DynamoDB table via serverless framework, added a secondary column index for "aaa_id":  Devices: Type: AWS::DynamoDB::Table Properties: TableName: Devices BillingMode: PAY_PER_REQUEST AttributeDefinitions: - AttributeName: serial AttributeType: S - AttributeName: aaa_id AttributeType: N KeySchema: - AttributeName: serial KeyType: HASH GlobalSecondaryIndexes: - IndexName: aaa_id KeySchema: - AttributeName: aaa_id KeyType: HASH Projection: ProjectionType: ALL  I want to query my DynamoDB and get all items of the table where the column "aaa_id" exists or isn't 0 (or null, if it's even possible for a Number type column). Some rows don't include it. preferable using the query method instead of scan since i know it's less heavy I've been on this for hours. please help. Some of my few fail attempts: import json import boto3 def lambda_handler(event, context): dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('Devices') try: response = table.query( IndexName='aaa_id', FilterExpression='aaa_id <> :empty', ExpressionAttributeValues={':empty': {'N': '0'}} ) items = response['Items'] return { 'statusCode': 200, 'body': json.dumps(items) } except Exception as e: print(e) return { 'statusCode': 500, 'body': json.dumps('Error querying the database') } ################################# import json import boto3 from boto3.dynamodb.conditions import Key, Attr def lambda_handler(event, context): dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('Devices') try: response = table.query( IndexName='aaa_id', KeyConditionExpression=Key('aaa_id').gt(0) & Attr('aaa_id').not_exists(), ExpressionAttributeValues={ ':empty': {'N': ''} } ) data = response['Items'] while 'LastEvaluatedKey' in response: response = table.query( IndexName='aaa_id', KeyConditionExpression=Key('aaa_id').gt(0) & Attr('aaa_id').not_exists(), ExpressionAttributeValues={ ':empty': {'N': ''} }, ExclusiveStartKey=response['LastEvaluatedKey'] ) data.extend(response['Items']) return { 'statusCode': 200, 'body': json.dumps(data), 'success': True } except Exception as e: return { 'statusCode': 500, 'body': json.dumps(str(e)), 'success': False } ####################### import json import boto3 from boto3.dynamodb.conditions import Key def lambda_handler(event, context): dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('Devices') try: response = table.query( IndexName='aaa_id-index', KeyConditionExpression=Key('aaa_id').gt(0) ) items = response['Items'] while 'LastEvaluatedKey' in response: response = table.query( IndexName='aaa_id-index', KeyConditionExpression=Key('aaa_id').gt(0), ExclusiveStartKey=response['LastEvaluatedKey'] ) items.extend(response['Items']) return { 'statusCode': 200, 'body': json.dumps(items), 'success': True } except Exception as e: return { 'statusCode': 500, 'body': json.dumps({'error': str(e)}), 'success': False } ################################## import boto3 import json def lambda_handler(event, context): dynamodb = boto3.client('dynamodb') try: response = dynamodb.query( TableName="Devices", IndexName='aaa_id-index', KeyConditionExpression='aaa_id <> :empty', # ExpressionAttributeValues={':empty': {'S': ''}} ) return { 'statusCode': 200, 'body': json.dumps(response['Items']), 'status': 'success' } except Exception as e: return { 'statusCode': 500, 'body': json.dumps({'error': str(e)}), 'status': 'error' } 

Answer: You're over complicating things. Firstly, a number type cannot be null, as DynamoDB is schemaless you simply omit any value. Secondly, indexes can be sparse. As you're not interested in items which are 0 then simply don't set a value for that, which in turn will mean the item won't exist in the index. Then you simply Scan the index, as you know that all values that are there are not null and are not 0. In this case Scan is efficient as it's reading exactly what you want. response = table.scan( IndexName='aaa_id' )