Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask/SQLAlchemy error: TypeError: Incompatible collection type: [model] is not list-like

i have nasty problem in very simple application. I try many different ways, but still cant figure out what I'm doing wrong.

I use Flask + flask.ext.sqlalchemy, also my model relationship is many-to-many.

authorship = db.Table('authorship',
    db.Column('author_id', db.Integer, db.ForeignKey('author.id')),
    db.Column('book_id', db.Integer, db.ForeignKey('book.id'))
)


class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80), unique=False)
    description = db.Column(db.String(), unique=False)

    authors = db.relationship('Author', secondary=authorship, backref=db.backref('books', lazy='dynamic'))

    def __init__(self, title, description, authors):
        self.title = title
        self.description = description
        self.authors = authors

    def __repr__(self):
        return self.title


class Author(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return self.name

No matter how i change my models and play with relationship i still have same error (Author or other model):

TypeError: Incompatible collection type: Author is not list-like

Error shows up when i try to add new book.

I use these models with WTForms:

@app.route('/add_book', methods=['GET', 'POST'])
def add_book():
    if not session.get('logged_in'):
        abort(401)
    form = AddBookForm(request.form)
    if request.method == 'POST' and form.validate():
        a = Author(form.author.data)
        b = Book(form.title.data, form.description.data, a)
        db.session.add(b)
        flash("book added")
    return render_template('add_book.html', form=form) 
like image 730
slovn Avatar asked Oct 26 '13 12:10

slovn


1 Answers

If I'm not mistaken that's a M2M relation Books - Authors, so instead of

b = Book(form.title.data, form.description.data, a)

you should probably do

b = Book(form.title.data, form.description.data, [a])

as it expects a list and you've given it just one object.

like image 84
Paweł Pogorzelski Avatar answered Sep 26 '22 02:09

Paweł Pogorzelski