Reputation: 4907
I am having some difficulty setting up a one to one relationship between two models in my flask application. I have two models Employee
and `Photo'. An employee has only one photo associated with it and vice-versa.
This is the code that I have in my models.py
file:
class Employee(db.Model):
__tablename__ = 'employees'
id = db.Column(db.Integer, primary_key=True)
photo = db.relationship("Photo", uselist=False, back_populates='employees')
class Photo(db.Model):
__tablename__ = 'photos'
id = db.Column(db.Integer, primary_key=True)
employee_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
employee = db.relationship('Photo', back_populates='photo')
I've followed the instruction on the SQL Alchemy documentation found hereSQL Alchemy simple relationships. The error that I keep encountering is shown below:
sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Photo.employee
- there are no foreign keys linking these tables.
Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
I clearly specify the foreign key right here employee_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
. I'm not sure what I'm doing wrong. Additionally, I was reading the documentation and it doesn't help that uselist, backref, and back_populates
are so similar.
Can someone assist me with this? Help would be greatly appreciated.
One to One relationship stack overflow question
Upvotes: 2
Views: 2168
Reputation: 127200
backref
automatically adds the reverse relationship to the related model. You can pass a db.backref
object to it to specify options to the relationship. back_populates
tells SQLAlchemy to populate an existing reverse relationship, rather than creating it. uselist
tells SQLAlchemy whether the relationship is a list or not, for cases where it can't determine that automatically.
In your example, you need one relationship, with one backref that is a single item.
You have two typos in your code. First, back_populates='employees'
should refer to 'employee'
, which is what you called the property on the related model. Second, employee = relationship('Photo'
is pointing at the wrong model, it should relate to Employee
.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
db.engine.echo = True
class Photo(db.Model):
id = db.Column(db.Integer, primary_key=True)
class Employee(db.Model):
id = db.Column(db.Integer, primary_key=True)
photo_id = db.Column(db.ForeignKey(Photo.id))
photo = db.relationship(Photo, backref=db.backref('employee', uselist=False))
db.create_all()
db.session.add(Employee(photo=Photo()))
db.session.commit()
print(Employee.query.get(1).photo)
Upvotes: 2