2017-10-07 57 views
1

我正在嘗試編寫一個Python腳本來訪問Amazon Redshift,以便在Redshift中創建表並將數據從S3複製到Redshift表。從Python訪問Redshift時出現「憑據無效」錯誤

我的代碼是:

import psycopg2 
import os 
#import pandas as pd 
import requests 
requests.packages.urllib3.disable_warnings() 

redshift_endpoint = os.getenv("END-point") 
redshift_user = os.getenv("user") 
redshift_pass = os.getenv("PASSWORD") 
port = 5439 
dbname = 'DBNAME' 
conn = psycopg2.connect(
    host="", 
    user='', 
    port=5439, 
    password='', 
    dbname='') 
cur = conn.cursor() 
aws_key = os.getenv("access_key") # needed to access S3 Sample Data 
aws_secret = os.getenv("secret_key") 
#aws_iam_role= os.getenv('iam_role') #tried using this too 

base_copy_string= """copy %s from 's3://mypath/%s'.csv 
credentials 'aws_access_key_id= %s aws_access_secrect_key= %s' 
delimiter '%s';""" # the base COPY string that we'll be using 

#easily generate each table that we'll need to COPY data from 
tables = ["employee"] 
data_files = ["test"] 
delimiters = [","] 
#the generated COPY statements we'll be using to load data; 
copy_statements = [] 
for tab, f, delim in zip(tables, data_files, delimiters): 
    copy_statements.append(base_copy_string % (tab, f, aws_key, aws_secret, delim)%) 
#create Table 
cur.execute(""" create table employee(empname varchar(30),empno integer,phoneno integer,email varchar(30))""") 
for copy_statement in copy_statements: # execute each COPY statement 
    cur.execute(copy_statement) 
conn.commit() 
for table in tables + ["employee"]: 
    cur.execute("select count(*) from %s;" % (table,))  
    print(cur.fetchone()) 
conn.commit() # make sure data went through and commit our statements permanently. 

當我在cur.execute運行此命令我得到一個錯誤(copy_statement)

**Error:** error: Invalid credentials. Must be of the format: credentials 'aws_iam_role=...' or 'aws_access_key_id=...;aws_secre 
t_access_key=...[;token=...]' 
    code:  8001 
    context: 
    query:  582 
    location: aws_credentials_parser.cpp:114 
    process: padbmaster [pid=18692] 

有沒有在我的代碼有問題嗎?還是它是一個AWS access_key問題?

我甚至使用iam_role嘗試,但我得到一個錯誤:

IAM role cannot assume role even in Redshift

我必須通過附加S3FullAccess政策管理IAM角色權限。

+0

你在你的base_copy_string中有一個錯字:'aws_access_secrect_key' –

回答

0

腳本中存在一些錯誤。

1)更改如下base_copy_string:

base_copy_string= """copy %s from 's3://mypath/%s.csv' credentials 'aws_access_key_id=%s;aws_secret_access_key=%s' delimiter '%s';""" # the base COPY string that we'll be using

必須有憑據,還可以其他格式問題與單引號加一個;。它是aws_secret_access_key而不是aws_access_secrect_key

檢查此鏈接瞭解詳細信息:http://docs.aws.amazon.com/redshift/latest/dg/copy-usage_notes-access-permissions.html#copy-usage_notes-iam-permissions

我建議你使用IAM-角色而不是憑據。 http://docs.aws.amazon.com/redshift/latest/dg/loading-data-access-permissions.html

2)改變copy_statements.append如下(刪除到底額外%):

copy_statements.append(base_copy_string % (tab, f, aws_key, aws_secret, delim))

改正這些問題並再試一次。

+0

謝謝,現在我得到這個錯誤copy_statements.append(base_copy_string%(tab,f,aws_key,aws_secret,delim)) TypeError:並非所有在字符串格式化過程中轉換的參數 –

+0

使用'str(variable_name)'爲類型變量串起來。可能aws_key和aws_secret導致錯誤。 'copy_statements.append(base_copy_string%(tab,f,str(aws_key),str(aws_secret),delim))' –

+0

我試過這樣也不行 –

1

首先,從不,從不,硬編碼訪問密鑰和祕密密鑰在您的代碼。這樣就排除了你的第一個查詢。現在正在實現事情的正確方式。你是對的,IAM角色是正確的做法。不幸的是,我無法從你的描述中得到確切的錯誤和用例。據我所知,你試圖從你的電腦(本地機器)運行這個python文件。因此,您需要爲您的IAM用戶附加權限才能訪問RedShift(以及您的代碼所觸及的所有其他服務)。如果我的假設錯誤,請糾正我。

+0

是的,那正是我想要做的。我試圖從S3發送數據到Redshift –

+0

正確的說法是從S3中提取數據。所以你需要給RedShift資源權限來訪問S3(你正在做的)。如果您在IAM角色的情況下附加錯誤的屏幕截圖,這將會很有幫助。 –

+0

----------------------------------------------- 錯誤:User arn:aws:redshift:us-east-1:028810420564:dbuser:my-cluster/venkat未被授權承擔IAM角色arn:aws:iam :: 028810420 564:role/redshift-s3 code:8001 上下文:IAM角色= ARN:AWS:IAM :: 028810420564:角色/紅移-S3 查詢:3209 位置:xen_aws_credentials_mgr.cpp:229個 過程:padbmaster [PID = 19102] -------- --------------------------------------- –

-1

就在,如果你錯過了 安裝AWS CLI 情況下運行 AWS配置 把你的證書和地區 希望這有助於。

+0

很難說出你寫的內容。請考慮編輯。 – norok2

+0

這是無關緊要的,因爲他沒有使用AWS CLI或boto或boto3等庫。他將自己的憑據傳遞給副本聲明本身。 –

相關問題