Flask SqlAlcheny TypeError: 'Fermentables' object is not iterable

0

In 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 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 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
    
asked by anonymous 25.06.2018 / 15:36

2 answers

0

I was able to solve the problem as follows Popular 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()

That way it works, although it does not look the way I want it, with each part divided into a function.

    
26.06.2018 / 16:17
0

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

In Python, objects separated by "," are a tuple - an iterable object - it may or may not be in parentheses - eg. (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 parentheses level remaining within the call to add_all : add_all((Fermentables(...))) - if you want a tuple with a single element in which add_all would work), you must have a comma inside the parentheses - this is the official way of indicating tuples of a single element: add_all((Fermentables(...),)) . But - reiterating what I said up there - you do not need the tuple, nor the extra pair of parentheses, nor call add_all to insert a single object in the database.

    
26.06.2018 / 14:30