8

I am working on updating some Python code I have been working with and was looking for some advice on the best way to deal with an idea I am working with. The part of my code that I wish to change is :

my_reader = csv.reader(input, delimiter = ',',quotechar='|')
mouse.executemany("INSERT INTO Example_Input (ID,Name,Job,Salary) VALUES (?,?,?,?)", my_reader)

The code works. My question is, can I change the "(?,?,?,?)" into something more dynamic like 'range()' to allow user input. I understand that I would also have to have a dynamic create table statement, so another solution might be to count the number of inputs.

To be a little more clear: for example if I had raw_input("How many variables does the table contain?: ") and the input was 2, the program would know to run as if (?,?).

Thoughts?

(also I am using SQLite3 and python 2.7)

3 Answers 3

8

Assuming your csv had a header field, you could use a DictReader and generate the field names and parameters its fieldnames property.

The constructor for DictReader allows you to specify the fieldnames if they are not in the file, so you could ask the user for that information if required.

Assuming the headers are in the file, this example code should work:

import csv
import sqlite3

#Give the table a name and use it for the file as well
table_name = 'Example'
a = open(table_name + '.csv', 'r')

#Use a dict reader
my_reader = csv.DictReader(a)
print my_reader.fieldnames # Use this to create table and get number of field values,etc.

# create statement
create_sql = 'CREATE TABLE ' + table_name + '(' + ','.join(my_reader.fieldnames) + ')'
print create_sql

#open the db
conn = sqlite3.connect('example.db')
c = conn.cursor()
# Create table using field names
c.execute(create_sql)
insert_sql = 'insert into ' + table_name + ' (' + ','.join(my_reader.fieldnames) + ') VALUES (' + ','.join(['?'] * len(my_reader.fieldnames))+ ')'
print insert_sql

values = []
for row in my_reader:
    row_values = []
    for field in my_reader.fieldnames:
        row_values.append(row[field])
    values.append(row_values)

c.executemany(insert_sql, values)
Sign up to request clarification or add additional context in comments.

1 Comment

I do know that some of the csv files do not have headers that contain the variable names... however this is definitely something I would consider and just state in the 'raw_input()' that the program will assume the document contains those headers.
4

On python3, using list comprehensions and dictionaries I came up with the following simple code that is capable of building a Dynamic SQLite insert string based on a given dictionary:

# Data to be inserted:

data = [
  {
    'table': 'customers',
    'values': {
      'name': '"Doctor Who"',
      'email': '"[email protected]"'
    }
  },
  {
    'table': 'orders',
    'values': {
      'customer_id': '1',
      'item': '"Sonic Screwdriver"',
      'price': '1000.00'
    }
  }
]


def generate_insert_query(dictionary):
  table = dictionary["table"]  # Get name of the table

  # Get all "keys" inside "values" key of dictionary (column names)
  columns = ', '.join(dictionary["values"].keys())  

  # Get all "values" inside "values" key of dictionary (insert values)
  values = ', '.join(dictionary["values"].values())

  # Generate INSERT query
  print(f"INSERT INTO {table} ({columns}) VALUES ({values})" + "\n")


# Generate QUERY for each dictionary inside data list
for query in data:
  generate_insert_query(query)

Try the code on: https://repl.it/KNZg/2

Comments

0

I recently wrote a function to quickly populate a table based on table name and a list of tuples with the row data that I wanted to insert. I am using the tuple to identify how many columns are expected:

def populate_table(table_name, data):
    #Grab first tuple and find out how many columns are expected to be edited
    num_columns = len(data[0])
    try:
        cursor.executemany("INSERT INTO {} VALUES({})".format(table_name, ','.join(['?' for s in xrange(num_columns)]), data)
        conn.commit()
    except sqlite3.OperationalError:
        ...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.