从 Python 访问 Redshift 时出现“无效凭据”错误

Posted

技术标签:

【中文标题】从 Python 访问 Redshift 时出现“无效凭据”错误【英文标题】:"Invalid credentials" error when accessing Redshift from Python 【发布时间】:2017-10-07 02:20:02 【问题描述】:

我正在尝试编写一个 Python 脚本来访问 Amazon Redshift 以在 Redshift 中创建一个表并将数据从 S3 复制到 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 角色即使在 Redshift 中也不能担任角色

我通过附加 S3FullAccess 策略获得了托管 IAM 角色权限。

【问题讨论】:

您的 base_copy_string 中有错字:aws_access_secrect_key 【参考方案1】:

您的脚本中有一些错误。

1) 更改 base_copy_string 如下:

base_copy_string= """从 's3://mypath/%s.csv' 凭证复制 %s 'aws_access_key_id=%s;aws_secret_access_key=%s' 分隔符 '%s';""" # 我们将使用的基本 COPY 字符串

必须在凭据中添加; 以及单引号的其他格式问题。是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-roles 而不是凭据。 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))

更正这些并重试。

【讨论】:

谢谢,现在我收到了这个错误 copy_statements.append(base_copy_string % (tab,f,aws_key,aws_secret,delim)) TypeError: not all arguments convert during string formatting 使用str(variable_name) 将变量类型化为字符串。可能是 aws_key 和 aws_secret 导致错误。 copy_statements.append(base_copy_string %(tab,f,str(aws_key),str(aws_secret),delim))【参考方案2】:

首先,从不、从不、从不在您的代码中硬编码访问密钥和秘密密钥。这样就排除了您的第一个查询。现在来到正确的实现方式。你是对的,IAM Role 是正确的做法。不幸的是,我无法从您的描述中得到确切的错误和用例。据我了解,您正在尝试从您的计算机(本地计算机)运行此 python 文件。因此,您需要为您的 IAM 用户附加权限才能访问 RedShift(以及您的代码涉及的所有其他服务)。如果我的假设是错误的,请纠正我。

【讨论】:

是的,这就是我想要做的。我正在尝试将数据从 S3 发送到 Redshift 正确的说法是从 S3 中提取数据。因此,您需要授予 RedShift 资源访问 S3 的权限(您正在这样做)。如果您可以在 IAM 角色的情况下附上错误的屏幕截图,将会很有帮助。 ------------------------------------------ ----- 错误:用户 arn:aws:redshift:us-east-1:028810420564:dbuser:my-cluster/venkat 无权承担 IAM 角色 arn:aws:iam::028810420 564:role/redshift- s3 代码:8001 上下文:IAM 角色 = arn:aws:iam::028810420564:role/redshift-s3 查询:3209 位置:xen_aws_credentials_mgr.cpp:229 进程:padbmaster [pid=19102] --------- -------------------------------------------------- 好的,我发现您的 IAM ARN 中有一个空格字符。 arn:aws:iam::028810420 564:角色/redshift-s3。这是无效的格式,可能在复制 IAM 的 ARN 时出错。除此之外,您要注意每次都指定整个 ARN。【参考方案3】:

以防万一你错过了 安装 AWS CLI 跑 aws 配置 输入您的凭据和区域 希望这会有所帮助。

【讨论】:

从您写的内容中很难判断该做什么。请考虑编辑。 这无关紧要,因为他没有使用 AWS CLI 或 boto 或 boto3 等库。他正在将他的凭据传递给副本声明本身。

以上是关于从 Python 访问 Redshift 时出现“无效凭据”错误的主要内容,如果未能解决你的问题,请参考以下文章

将数据从本地复制到 S3 到 Redshift 表时出现问题

在 redshift 中查询时出现权限错误

从节点 jdbc 访问 Redshift 数据时抛出错误

无法从 Redshift 读取列名有空格的数据

在 Postgres (Redshift) 中使用两个选择列运行 MAX 聚合查询时出现问题

WindowsError:异常:使用从 C++ 到 Python 的 ctypes 创建 DLL 时出现访问冲突或 Windows 错误 193