Javier Cárdenas
Javier Cárdenas

Reputation: 4045

Flask sqlalchemy - error binding parameter 0

I'm learning to develop a web app with flask but now I'm stuck with this error using flask-sqlalchemy:

Original exception was: (InterfaceError) Error binding parameter 0 - probably unsupported type. 
u'INSERT INTO standards (std_insumo_id, std_name_id, cantidad, viviendas) VALUES (?, ?, ?, ?)' (...)",))

These are my models

class Insumo(db.Model):
    __tablename__ = 'insumos'
    codigo = db.Column(db.Integer, primary_key=True)
    descripcion = db.Column(db.String(64), unique=True)
    um = db.Column(db.String(64))


class StandardName(db.Model):
    __tablename__ = 'std_names'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    standards = db.relationship('Standard', backref='std_name')


class Standard(db.Model):
    __tablename__ = 'standards'
    id = db.Column(db.Integer, primary_key=True)
    std_insumo_id = db.Column(db.Integer, db.ForeignKey('insumos.codigo'))
    std_name_id = db.Column(db.Integer, db.ForeignKey('std_names.id'))
    cantidad = db.Column(db.Float)
    viviendas = db.Column(db.Integer)

And this is what i'm doing when im trying to insert the row:

cemento = Insumo.query.filter_by(descripcion="Cemento").first()
mamp = StandardName.query.filter_by(name="Mamposteria").first()

These two already exist in the db, so there is no problem. The problem arises when I'm trying to use model: Standard

r1 = Standard(std_insumo_id=cemento, std_name_id=mamp, cantidad=10, viviendas=40)
db.session.add(r1)
db.session.commit()

Could you help me understand what is happening? I don't see anything wrong with the types.

Upvotes: 0

Views: 1403

Answers (1)

SingleNegationElimination
SingleNegationElimination

Reputation: 156278

here:

r1 = Standard(std_insumo_id=cemento, ...)
#             ^^^^^^^^^^^^^^^^^^^^^

Standard is expecting a value for std_insumo_id, which is supposed to be an int, per the declaration here:

std_insumo_id = db.Column(db.Integer, db.ForeignKey('insumos.codigo'))

But you have

cemento = Insumo.query.filter_by(descripcion="Cemento").first()

So cemento is instance of Insumo, not an int. you can do those sorts of things, but you need to provide a class level mapping in addition to the column level mapping, with relationship()

class Standard(db.Model):
    std_insumo_id = db.Column(db.Integer, db.ForeignKey('insumos.codigo'))
    std_insumo = relationship(Insumo)

and then

r1 = Standard(std_insumo=cemento, ...)
^             ^^^^^^^^^^

without "_id"

Upvotes: 3

Related Questions