0

I’m setting up a new flask app, and I'm using sqlite3 as DB. It is possible to maintain the setup even if I have to insert 5 values?

def encrypt():
    now = datetime.now()
    date_time = now.strftime("%d/%m/%Y - %H:%M")
    filename = secure_filename(request.form['filename'].replace(" ", "_").replace("(", "").replace(")", ""))
    password = request.form['password']
    username = session.get('username')
    id = request.form['id']
    type = infile[-4:]
    file = filename[:-4] + '.enc'
    infile = os.path.join(app.config['DATA_FOLDER'], filename)
    outfile = os.path.join(app.config['DATA_FOLDER'], filename[:-4] + '.enc')
    con = sqlite3.connect(app.config['DataBase'])
    cur = con.cursor()
    cur.executemany('INSERT INTO keys (id, file, type, date_time, attempts) VALUES (?,?,?,?,?)', id, file, type, date_time, "0")
    con.commit()
    con.close()
    return 'ok'

The following error is shown in logs:

File "./myapp.py", line 524, in encrypt
    cur.executemany('INSERT INTO keys (id, file, type, date_time, attempts) VALUES (?,?,?,?,?)', id, file, type, date_time, "0")
TypeError: function takes exactly 2 arguments (6 given)
davidism
  • 121,510
  • 29
  • 395
  • 339
Cravenica
  • 169
  • 10
  • Like the error says, `executemany()` takes two arguments, not 6. Plus it's likely not the method you want anyways - normal `execute()` would be more appropriate since you're just inserting one row. – Shawn Sep 06 '19 at 07:58

1 Answers1

1

Firstly, you don't need to use executemany as that is used when you want to insert multiple rows into a single table. What you have there is just multiple values that will represent a single row. Use placeholders for the values in the SQL statement, and pass a tuple as the second argument to execute.

cur.execute('INSERT INTO keys (id, file, type, date_time, attempts) VALUES (?, ?, ?, ?, ?)', (id, file, type, date_time, "0"))



Bonus answer (the executemany case)


Now, when you want to insert multiple rows in the same table, you'd use the cursor.executemany method. And that takes 2 arguments, like you've found out in your error above:

  1. a string, which represents the SQL query
  2. a collection of parameters, where each parameter is a list of values representing a row

The sql query is executed against all parameters in the collection.

Working example with both execute and executemany that can be pasted in a Python file and run

import sqlite3

conn = sqlite3.connect(':memory:')

cursor = conn.cursor()
cursor.execute('CREATE TABLE person (first_name text, last_name text, age integer)')
cursor.execute('SELECT * FROM person')
print(cursor.fetchall())  # outputs []

first_name, last_name, age = 'Carl', 'Cox', 47
cursor.execute('INSERT INTO person (first_name, last_name, age) VALUES (?, ?, ?)', (first_name, last_name, age))
cursor.execute('SELECT * FROM person')
print(cursor.fetchall())  # outputs [('Carl', 'Cox', 47)]

many_values = [
    ('Boris', 'Brejcha', 37),
    ('Mladen', 'Solomun', 43),
]
cursor.executemany('INSERT INTO person (first_name, last_name, age) VALUES (?, ?, ?)', many_values)
cursor.execute('SELECT * FROM person')
print(cursor.fetchall())  # outputs [('Carl', 'Cox', 47), ('Boris', 'Brejcha', 37), ('Mladen', 'Solomun', 43)]

conn.close()

So you see in the executemany case how the method takes just 2 parameters, but the 2nd parameter is a sequence of sequences.

davidism
  • 121,510
  • 29
  • 395
  • 339
Marius Mucenicu
  • 1,685
  • 2
  • 16
  • 25