['NoneType'错误,使用Python SSHTunnelForwarder

问题描述 投票:0回答:2

我正在尝试整理一个将按计划运行的脚本,以更新位于云中的数据库。即时通讯使用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
python mysql pandas ssh-tunnel
2个回答
0
投票

我会说这是预期的。像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


0
投票

使用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.")
© www.soinside.com 2019 - 2024. All rights reserved.