0

I have simple example from a book about using SQLAlchemy on 1st level, which is close to DB-API. Since this book came out it's syntax changed and I have to modify code to have it worked. I have a problem inserting row in a table, using positional placeholders in a pre-writen string. Here is the code:

import sqlalchemy as sa
from sqlalchemy import text

engine = sa.create_engine('sqlite://')

with engine.connect() as conn:

    print (conn)
    conn.execute(text('''CREATE TABLE zoo (
                 critter VARCHAR(20) PRIMARY KEY,
                 count INT,
                 damage FLOAT)'''))

    ins = text('INSERT INTO zoo (critter, count, damage) VALUES (?,?,?)')
    conn.execute (ins, [('bear', 2, 1000.0)])
    conn.execute (ins, [('weasel', 1, 2000.0)])

    rows = conn.execute('SELECT * FROM zoo')
    for row in rows:
       print (row)

for some reason, it raises this:

'<' not supported between instances of 'int' and 'str'

...although I do not matching anything and values order seems to be right (for the corresponding columns). Please, help to understand what is wrong here?

7
  • I'm not sure why this has been downvoted; it has a runnable minimal reproducible example, and while the root cause might be obvious to an experienced user, the error raised is not very helpful. Commented Apr 15 at 7:32
  • always put full error message because there are other useful information.
    – furas
    Commented Apr 15 at 15:03
  • documentation for Connection.execute suggests that it has to be dictionary or list of dictonaries but not list of tuple(s). As I remeber you can use tuple when you use directly module sqlite3 instead of sqlalchemy
    – furas
    Commented Apr 15 at 15:13
  • @furas ok I will remember this for the future Commented Apr 15 at 20:18
  • @furas unfortunately in the error message there was info about list of dictionaries or tuples, although in documentation I see now it is different. Thank you for the link! Commented Apr 15 at 20:26

1 Answer 1

1

The issue seems related to how you pass the parameters to the execute method.

Try this one

import sqlalchemy as sa
from sqlalchemy import text

engine = sa.create_engine('sqlite://')

with engine.connect() as conn:
    # Create table
    conn.execute(text('''CREATE TABLE zoo (
                 critter VARCHAR(20) PRIMARY KEY,
                 count INT,
                 damage FLOAT)'''))

    # Fix 1: Pass parameters as a dictionary or direct values, not as a list of tuples
    ins = text('INSERT INTO zoo (critter, count, damage) VALUES (:critter, :count, :damage)')
    
    # Option 1: Using named parameters
    conn.execute(ins, {"critter": "bear", "count": 2, "damage": 1000.0})
    conn.execute(ins, {"critter": "weasel", "count": 1, "damage": 2000.0})
    
    # OR Option 2: Using positional parameters with proper syntax
    # ins = text('INSERT INTO zoo (critter, count, damage) VALUES (?, ?, ?)')
    # conn.execute(ins, ["bear", 2, 1000.0])  # Pass values directly, not as a list of tuples
    
    # Fetch results
    result = conn.execute(text('SELECT * FROM zoo'))
    for row in result:
        print(row)
1
  • Thank you for answering! The dictionary method seems to work. Howewer, if you try to pass it with positional params just like tuple or just like list (list in your example) there is another error which says that "the list argument must be dictionary or tuple". This is the reason I used tuple inside of list. And after that - this type matching problem appeared. I was hoping to understand reason for this, but since 1'st option is working I guess this is not realy important for the moment. UPD. My mistake in the results output setion, corrected it :) Commented Apr 15 at 1:40

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.