使用golang和AWS进行编程的新手。 我的函数中的代码块,尝试创建一个新表和写 使用AWS DynamoDB为其赋值。 创建成功,但是当Write发生时程序崩溃。 不确定为什么......如果有人能帮帮我,我真的很感激!
**Logs**:
2015/07/22 15:46:46 TableStatus: 0xc208193cb0
2015/07/22 15:46:46 End
2015/07/22 15:46:48 Sleep 2: Before Write
2015/07/22 15:46:48 Before Defining Input
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x401b28]
**Code Block:**
{
log.Println("Entry+++")
cfg := aws.DefaultConfig
svc := dynamodb.New(cfg)
tableDefinition := &dynamodb.CreateTableInput{
TableName: aws.String("table1"),
AttributeDefinitions: make([]*dynamodb.AttributeDefinition, 1, 1),
KeySchema: make([]*dynamodb.KeySchemaElement, 1, 1),
ProvisionedThroughput: &dynamodb.ProvisionedThroughput{
ReadCapacityUnits: aws.Long(1),
WriteCapacityUnits: aws.Long(1),
},
}
tableDefinition.KeySchema[0] = &dynamodb.KeySchemaElement{
AttributeName: aws.String("batch_id"),
KeyType: aws.String("HASH"),
}
tableDefinition.AttributeDefinitions[0] = &dynamodb.AttributeDefinition{
AttributeName: aws.String("batch_id"),
AttributeType: aws.String("S"),
}
resp, err := svc.CreateTable(tableDefinition)
log.Println("After CreateTable---")
if err != nil {
log.Println("create table failed", err.Error())
return
}
if resp != nil && resp.TableDescription != nil {
log.Println(
"TableStatus:", resp.TableDescription.TableStatus)
}
log.Println("End")
//Some time before the createTable transaction gets committed.
time.Sleep(2 * time.Second)
log.Println("Sleep 2 Before Write")
testA := "batch_1" //value to be written to the db
// testB := "batch_name"
// testC := "530"
// testD := "Sample-Keyy-98"
log.Println("Before Defining Input")
input := &dynamodb.PutItemInput{
TableName: aws.String("table1"),
Item: map[string]*dynamodb.AttributeValue{
"batch_id": &dynamodb.AttributeValue{
S: aws.String(testA),
},
// "name": &dynamodb.AttributeValue{
// S: aws.String(testB),
// },
},
}
_, err2 := svc.PutItem(input)
}
答案 0 :(得分:2)
如果您可以显示错误的堆栈跟踪,那将非常有用。但在此之前,我可以说当您尝试访问任何未初始化变量的成员时,通常会发生此错误。 例如,如果此错误出现在以下行
a := b.c
然后你需要检查b是否正确初始化。很可能b的值是nil因此nil指针取消引用。
答案 1 :(得分:1)
Following is what I could come up with from whatever I read across the net.
Working on local secondary indexes, range index and timestamps presently.
Thanks again!
package main
import (
"github.com/aws/aws-sdk-go/aws"
// "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/aws/aws-sdk-go/service/dynamodb"
"log"
"strconv"
"time"
)
type dynamo struct {
db *dynamodb.DynamoDB
tableName string
readCapacity int64
writeCapacity int64
}
type metadata struct {
dynamoDb *dynamo
batchID string
field1 string
field2 string
batchSize int //In Bytes
}
func newDynamo(name string, readCapacity, writeCapacity int64) *dynamo {
cfg := aws.DefaultConfig
return &dynamo{
db: dynamodb.New(cfg),
tableName: name,
readCapacity: readCapacity,
writeCapacity: writeCapacity,
}
}
func newMetadata(batchID, field1Val, field2Val string, batchSizeVal int) *metadata {
return &metadata{
batchID: batchID,
field1: field1Val,
field2: field2Val,
batchSize: batchSizeVal,
}
}
var dynDB *dynamo
var m *metadata
func main() { //create the *metadata struct object, and it can then call writeToDynamo fn
log.Println("Entry")
dynDB = newDynamo("tableName", 1, 1) //make a new dynamo struct object
dynDB.createTable()
m = newMetadata("field1Value", "field2Value", 232)
m.setDynamoDB()
m.writeToDynamo()
log.Println("Exit")
}
func (d *dynamo) createTable() (err error) {
log.Println("createTable Entry")
tableDefinition := &dynamodb.CreateTableInput{
TableName: aws.String(d.tableName),
AttributeDefinitions: []*dynamodb.AttributeDefinition{ // Required
{ // Required
AttributeName: aws.String("batchID"),
AttributeType: aws.String("S"), // Required
},
},
KeySchema: []*dynamodb.KeySchemaElement{ // Required
{ // Required
AttributeName: aws.String("batchID"),
KeyType: aws.String("HASH"), // Required
},
},
ProvisionedThroughput: &dynamodb.ProvisionedThroughput{
ReadCapacityUnits: aws.Long(d.readCapacity),
WriteCapacityUnits: aws.Long(d.writeCapacity),
},
}
resp, err := dynDB.db.CreateTable(tableDefinition)
log.Println("After CreateTable---")
if err != nil {
log.Println("create table failed", err.Error())
return err
}
if resp != nil && resp.TableDescription != nil {
log.Println("TableStatus:", resp.TableDescription.TableStatus)
}
log.Println("CreateTable Exit")
//Sleep for 15 seconds, this is better when put in a function that validates the table that was created,
//But for testing, the program is put to sleep for 15 seconds. Program may fail if writeToDynamo is exedcuted
//without the table being in ACTIVE state.
time.Sleep(15 * time.Second)
return
}
func (m *metadata) writeToDynamo() {
log.Println("writeToDynamo")
//Not exactly able to figure out what was wrong with the prev code snippet
params := &dynamodb.PutItemInput{
TableName: aws.String(m.dynamoDb.tableName),
Item: map[string]*dynamodb.AttributeValue{
"batchID": &dynamodb.AttributeValue{
S: aws.String(m.batchID),
},
"field2": &dynamodb.AttributeValue{
S: aws.String(m.field2),
},
"field3": &dynamodb.AttributeValue{
S: aws.String(m.field3),
},
"batchSize": &dynamodb.AttributeValue{
N: aws.String(strconv.Itoa(m.batchSize_Compressed)),
},
},
}
resp2, err2 := dynDB.db.PutItem(params)
if err2 != nil {
// if awsErr, ok := err2.(awserr.Error); ok { // Generic AWS error with Code, Message, and original error (if any)
// log.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
// if reqErr, ok := err.(awserr.RequestFailure); ok {
// // A service error occurred
// log.Println(reqErr.Code(), reqErr.Message(), reqErr.StatusCode(), reqErr.RequestID())
// }
// } else { // This case should never be hit, the SDK should always return an //
// //error which satisfies the awserr.Error interface.
// log.Println(err2.Error())
// }
log.Println("Error while Writing:", err2.Error())
}
log.Println("Response:", awsutil.StringValue(resp2))
}
func (m *metadata) setDynamoDB() {
m.dynamoDb = dynDB
}