简体   繁体   中英

Error in One to Many SQLAlchemy database with Flask

I am currently trying to insert items into my database. I am using SQLlite and SQLAlchemy with Flask but there seems to be an issue. Whenever I try to insert items manually from the cmd, I receive an error.

This session's transaction has been rolled back due to a previous exception during flush.

I have implemented an one to many relationship in my database but something seems to keep messing up. Here is my Python code:

from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap

main = Flask(__name__)
db = SQLAlchemy(main)
main.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://YYYYYYY:XXXXXXX@localhost/address'
main.config['SECRET_KEY'] = 'something-secret'
Bootstrap(main)


class Organisation(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(40), unique=True)
    number = db.Column(db.String(40), unique=True)
    employees = db.relationship('Person', backref='employer', lazy='dynamic')

    def __init__(self, title, email, number):
        self.title = title
        self.email = email
        self.number = number



class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(60), unique=False)
    email = db.Column(db.String(40), unique=True)
    mobile = db.Column(db.String(40), unique=True)
    employer_id = db.Column(db.Integer, db.ForeignKey('organisation.id'))

    def __init__(self, name, email, mobile, employer_id):
        self.name = name
        self.email = email
        self.mobile = mobile
        self.employer_id = employer_id



@main.route('/', methods=['GET'])
def index():
    result = Person.query.all()
    org_result = Organisation.query.all()
    return render_template("index.html", result=result, org_result=org_result)


@main.route('/additems', methods=['GET'])
def additems():
    return render_template('add.html')


@main.route('/add', methods=['GET', 'POST'])
def add():
    person = Person(request.form['name'], request.form['email'], request.form['mobile'])
    db.session.add(person)
    db.session.commit()


if __name__ == "__main__":
    main.run(debug=True)

If I have to honest, I think that my issue is somewhere in the init functions. I have tried changing them in several ways:

1.Adding employees as self.employees = employees and trying directly to input an Organisation as: organisation_one=Organisation(title="XX",email="xx@mail.com",number="3838",employees=person_one) but it fired back an error even before I could submit person_one

2.I have tried referencing the employer_id in the Person __init__ file and when I try to add the organisation id, I recive an error "can't adapt type".

What am I doing wrong with the one to many database model? Can someone help me out?

Your database models require a __tablename__ attribute like this: This tells it what the actual table name is in the database. Otherwise SQLAlchemy doesn't know how to write the SQL for you.

class Organisation(db.Model):
    __tablename__ = 'organisation'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(40), unique=True)
    number = db.Column(db.String(40), unique=True)
    employees = db.relationship('Person', backref='employer', lazy='dynamic')

    def __init__(self, title, email, number):
        self.title = title
        self.email = email
        self.number = number

You must also reference this table name in the backref for your Person model:

db.ForeignKey('organisation.id'))  # assuming "organisation" is the table name

Also, your /add route is incomplete and will result in an error:

@main.route('/add', methods=['GET', 'POST'])
def add():
    person = Person(request.form['name'], request.form['email'], request.form['mobile'])
    db.session.add(person)
    db.session.commit()
    # e.g. add some instruction here on what to do...
    flash('Person %s <%s>added!' % (request.form['name'], request.form['email']))
    return redirect(url_for('main.additems'))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM