我正在尝试整理一个将按计划运行的脚本,以更新位于云中的数据库。即时通讯使用SSHTunnelForwarding与我的数据库建立连接。它全部打包在一个函数中,因此我要做的就是在函数中传递查询字符串并运行。此功能可在CSV内循环遍历约1000行数据。将每一行更改为正确的格式,并创建一个sql表达式。
with open (CSV, 'r') as f:
reader = csv.reader(f)
data = next(reader)
#load new data
for newrow in reader:
row = []
for val in newrow:
try:
val = float(val)
except:
val = "'"+val.strip()+"'"
row.append(val)
id = row[0]
phase_order = row[1]
Ajera_Project_Key = row[2]
project_id = row[3]
Project_Description = row[4]
Ajera_Client_Key = row[5]
Client = row[6]
Ajera_PM_Key = row[7]
Project_Manager = row[8]
Ajera_PIC_Key = row[9]
Principal_In_Charge = row[10]
title = row[11]
Ajera_Dept_Key = row[12]
Project_Status = row[13]
Phase_Status = row[14]
Department = row[15]
Project_Type = row[16]
start = row[17]
end = row[18]
hours_budgeted = row[19]
Hours_Worked = row[20]
Hours_Remaining = row[21]
Total_Contract_Amount = row[22]
Billed = row[23]
Billed_Labor = row[24]
Billed_Hours = row[25]
WIP = row[26]
Spent = row[27]
Spent_Labor = row[28]
FTEs = row[29]
q = 'INSERT INTO project_phases_test VALUES ({0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21},{22},{23},{24},{25},{26},{27},{28},{29});'.format(id,phase_order,Ajera_Project_Key,project_id,Project_Description,Ajera_Client_Key,Client,Ajera_PM_Key,Project_Manager,Ajera_PIC_Key,Principal_In_Charge,title,Ajera_Dept_Key,Project_Status,Phase_Status,Department,Project_Type,start,end,hours_budgeted,Hours_Worked,Hours_Remaining,Total_Contract_Amount,Billed,Billed_Labor,Billed_Hours,WIP,Spent,Spent_Labor,FTEs)
print (q)
query(q)
我遇到的问题是,当我尝试输入简单选择以外的查询字符串时。我传递给它的每个插入,更新,删除语句,都会收到一个错误消息,提示“ NoneType”对象不可迭代。但是,正如我之前提到的,如果我通过了一条select语句,则会得到我正在寻找的结果,而不会出现任何错误。
这里是功能
def query(q):
try:
with SSHTunnelForwarder(
(host, 22),
ssh_username=ssh_username,
ssh_password=ssh_password,
ssh_private_key=ssh_private_key,
remote_bind_address=(localhost, 3306)
) as server:
conn = db.connect(host=localhost,
port=server.local_bind_port,
user=user,
passwd=password,
db=database)
pd.read_sql_query(q, conn)
conn.close()
return
except Exception as e:
print e
pass
错误来自print e语句。
完整错误
Traceback (most recent call last):
File "C:\MAMP\htdocs\WIGHTcloud\dataLoader\load\loader.py", line 183, in <module>
query(drop) # drop phases table
File "C:\MAMP\htdocs\WIGHTcloud\dataLoader\load\loader.py", line 140, in query
pd.read_sql_query(q, conn)
File "C:\Python27\ArcGIS10.6\lib\site-packages\pandas\io\sql.py", line 431, in read_sql_query
parse_dates=parse_dates, chunksize=chunksize)
File "C:\Python27\ArcGIS10.6\lib\site-packages\pandas\io\sql.py", line 1600, in read_query
columns = [col_desc[0] for col_desc in cursor.description]
TypeError: 'NoneType' object is not iterable
我会说这是预期的。像SELECT这样的指令将产生输出,包括表头。
而其他DDL语句不产生输出,因此在pd.read_sql_query函数中引发异常。
您应该考虑检索游标,并在其上执行DDL语句,例如
mycursor = conn.cursor()
sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"
val = ("John", "Highway 21")
mycursor.execute(sql, val)
此处有更多信息:https://www.w3schools.com/python/python_mysql_insert.asp
使用nilleb所说的,我将其插入sshTunnelForwarder并使其正常工作。
with sshtunnel.SSHTunnelForwarder(ssh_address_or_host = ssh_host,
ssh_username = ssh_username,
ssh_password = ssh_password,
ssh_pkey = ssh_pkey,
remote_bind_address=('localhost', 3306),
) as tunnel:
mydb = mysql.connector.connect(
host=localhost,
user=sql_username,
passwd=sql_password,
database=db_name,
port=tunnel.local_bind_port
)
mycursor = mydb.cursor()
sql = "INSERT INTO customers (name, address) VALUES (%s, %s)"
val = ("John", "Highway 21")
mycursor.execute(sql, val)
mydb.commit()
print(mycursor.rowcount, "record inserted.")