Flask Sqlalcheny Typeerror: 'Fermentables' Object is not iterable

Asked

Viewed 220 times

1

In the model FermentableTypes:

class FermentableTypes(db.Model):
    __tablename__ = "fermentable_types"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    desc = db.Column(db.String(255))
    def __str__(self):
        return self.name

In the model FermentableProducers:

class FermentableProducers(db.Model):
    __tablename__ = "fermentable_producers"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    desc = db.Column(db.String(255))
    def __str__(self):
        return self.name

In the model Fermentables:

class Fermentables(db.Model):
    __tablename__ = "fermentables"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    desc = db.Column(db.String(255))
    ppg = db.Column(db.Integer)
    color = db.Column(db.Integer)
    fermentable_types_id = db.Column(db.Integer, db.ForeignKey('fermentable_types.id'))
    fermentable_types = db.relationship('FermentableTypes', backref=db.backref('fermentables', lazy='dynamic'))
    fermentable_producers_id = db.Column(db.Integer, db.ForeignKey('fermentable_producers.id'))
    fermentable_producers = db.relationship('FermentableProducers', backref=db.backref('fermentables', lazy='dynamic'))

Popular the database:

db.session.add_all((
    FermentableProducers(name='Agrária'),
    FermentableProducers(name='Castle Malting')))
db.session.commit()
db.session.add_all((
    FermentableTypes(name='Malte de cevada'),
    FermentableTypes(name='Malte de trigo'),
    FermentableTypes(name='Mel')))
    db.session.commit()
db.session.add_all((
    Fermentables(
        name='Malte Pilsen',
        desc='Malte Extra Pilsen usada pelas principais cervejarias da Mundo. \
Possui alto poder diastático o que resulta em um tempo de sacarificação menor.',
        ppg='35',
        color='2,8',
        fermentable_producers='Agrária',
        fermentable_types='Malte de cevada')))
    db.session.commit()

Error:

Traceback (most recent call last):
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/flask/app.py", line 1808, in full_dispatch_request
    self.try_trigger_before_first_request_functions()
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/flask/app.py", line 1855, in try_trigger_before_first_request_functions
    func()
  File "/home/carlos/code/brewblog/__init__.py", line 46, in create_admin_user
    populate_fermentable()
  File "/home/carlos/code/brewblog/utils.py", line 49, in populate_fermentable
    fermentable_types_id='1')
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/sqlalchemy/orm/scoping.py", line 153, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "/home/carlos/code/env-python3/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 1784, in add_all
    for instance in instances:
TypeError: 'Fermentables' object is not iterable

2 answers

0

If you are going to add only one object to the database, use db.session.add, the method add_all is for an eternal object - in your case you must have copied the code from somewhere that added a tuple of objects - they would be at the lowest level of parentheses, separated by ",".

In Python, objects separated by "," are a tuple - an eternal object - it may or may not be in parentheses - e.g.. (2, 5). But a single object in parentheses is just the value of an expression - the parentheses are then discarded - in your case there is a level parentheses left inside the call to add_all: add_all((Fermentables(...))) - if you want a tuple with a single element (in which case the add_all funcia), has to have a comma within the parentheses - is the official way of indicating tuples of a single element: add_all((Fermentables(...),)). But- reiterating what I said upstairs - you don’t need the tuple, or the extra pair of parentheses, or calling the add_all to insert a single object into the bank.

  • Not only that, because I tested the 2 ways that you propose and it didn’t work, but thank you

  • that error is why - is well visible in the code above.

0


I managed to solve the problem as follows
Popular the database:

malte_cevada = FermentableTypes(name='Malte de cevada')
malte_trigo = FermentableTypes(name='Malte de trigo')
db.session.add_all((malte_cevada, malte_trigo))

agraria = FermentableProducers(name='Agrária')
cargil = FermentableProducers(name='Cargil')
db.session.add_all((agraria, cargil))

db.session.add_all((
    Fermentables(
        name='Malte Pilsen',
        desc='Malte Extra Pilsen usada pelas principais cervejarias da Mundo. Possui alto poder diastático o que resulta em um tempo de sacarificação menor.',
        ppg='35',
        color='2.8',
        fermentable_producers=cargil,
        fermentable_types=malte_cevada),
    Fermentables(
        name='Malte Pilsen',
        desc='Malte Extra Pilsen usada pelas principais cervejarias da Mundo. Possui alto poder diastático o que resulta em um tempo de sacarificação menor.',
        ppg='35',
        color='2.8',
        fermentable_producers=agraria,
        fermentable_types=malte_cevada),
))
db.session.commit()

This way it works, although it does not stay the way I wanted, with each part divided into a function.

  • Note that you now have a tuple with two elements in the call to add_all - what I wrote in my reply is correct. Perhaps you have had some other error in simply trying to write .add instead of .add_all - but the "Object is not iterable" is why you were not passing a tuple.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.