MacLochlainns Weblog

Michael McLaughlin's Technical Blog

Site Admin

Read CSV with Python

without comments

In 2009, I showed an example of how to use the MySQL LOAD DATA INFILE command. Last year, I updated the details to reset the secure_file-priv privilege to use the LOAD DATA INFILE command, but you can avoid that approach with a simple Python 3 program like the one in this example. You also can use MySQL Shell’s new parallel table import feature, introduced in 8.0.17, as noted in a comment on this blog post.

The example requires creating an avenger table, avenger.csv file, a readWriteData.py Python script, run the readWriteData.py Python script, and a query that validates the insertion of the avenger.csv file’s data into the avenger table. The complete code in five steps using the sakila demonstration database:

  • Creating the avenger table with the create_avenger.sql script:

    -- Conditionally drop the avenger table.
    DROP TABLE IF EXISTS avenger;
     
    -- Create the avenger table.
    CREATE TABLE avenger
    ( avenger_id    int unsigned PRIMARY KEY AUTO_INCREMENT
    , first_name    varchar(20)
    , last_name     varchar(20)
    , avenger_name  varchar(20))
      ENGINE=InnoDB
      AUTO_INCREMENT=1001
      DEFAULT CHARSET=utf8mb4
      COLLATE=utf8mb4_0900_ai_ci;
  • Create the avenger.csv file with the following data:

    Anthony,Stark,Iron Man
    Thor,Odinson,God of Thunder
    Steven,Rogers,Captain America
    Bruce,Banner,Hulk
    Clinton,Barton,Hawkeye
    Natasha,Romanoff,Black Widow
    Peter,Parker,Spiderman
    Steven,Strange,Dr. Strange
    Scott,Lange,Ant-man
    Hope,van Dyne,Wasp
  • Create the readWriteFile.py Python 3 script:

    # Import libraries.
    import csv
    import mysql.connector
    from mysql.connector import errorcode
    from csv import reader
     
    #  Attempt the statement.
    # ============================================================
    #  Use a try-catch block to manage the connection.
    # ============================================================
    try:
      # Open connection.
      cnx = mysql.connector.connect( user='student'
                                   , password='student'
                                   , host='127.0.0.1'
                                   , database='sakila')
      # Create cursor.
      cursor = cnx.cursor()
     
      # Open file in read mode and pass the file object to reader.
      with open('avenger.csv', 'r') as read_obj:
        csv_reader = reader(read_obj)
     
        # Declare the dynamic statement.
        stmt = ("INSERT INTO avenger "
                "(first_name, last_name, avenger_name) "
                "VALUES "
                "(%s, %s, %s)")
     
        # Iterate over each row in the csv using reader object
        for row in csv_reader:
          cursor.execute(stmt, row)
     
        # Commit the writes.
        cnx.commit()
     
        #close the connection to the database.
        cursor.close()
     
    # Handle exception and close connection.
    except mysql.connector.Error as e:
      if e.errno == errorcode.ER_ACCESS_DENIED_ERROR:
        print("Something is wrong with your user name or password")
      elif e.errno == errorcode.ER_BAD_DB_ERROR:
        print("Database does not exist")
      else:
        print("Error code:", e.errno)        # error number
        print("SQLSTATE value:", e.sqlstate) # SQLSTATE value
        print("Error message:", e.msg)       # error message
     
    # Close the connection when the try block completes.
    else:
      cnx.close()
  • Run the readWriteFile.py file:

    python3 readWriteFile.py
  • Query the avenger table:

    SELECT * FROM avenger;

    It returns:

    +------------+------------+-----------+-----------------+
    | avenger_id | first_name | last_name | avenger_name    |
    +------------+------------+-----------+-----------------+
    |       1001 | Anthony    | Stark     | Iron Man        |
    |       1002 | Thor       | Odinson   | God of Thunder  |
    |       1003 | Steven     | Rogers    | Captain America |
    |       1004 | Bruce      | Banner    | Hulk            |
    |       1005 | Clinton    | Barton    | Hawkeye         |
    |       1006 | Natasha    | Romanoff  | Black Widow     |
    |       1007 | Peter      | Parker    | Spiderman       |
    |       1008 | Steven     | Strange   | Dr. Strange     |
    |       1009 | Scott      | Lange     | Ant-man         |
    |       1010 | Hope       | van Dyne  | Wasp            |
    +------------+------------+-----------+-----------------+
    10 rows in set (0.00 sec)

Written by maclochlainn

December 12th, 2021 at 12:17 am