class Geolocation(db.Model):
__tablename__ = "geolocation"
id = db.Column(db.Integer, primary_key=True)
latitude = db.Column(db.Float)
longitude = db.Column(db.Float)
elevation = db.Column(db.Float) # Meters
# Relationships
pin = db.relationship('Pin', uselist=False, backref="geolocation")
def __init__(self, latitude, longitude, elevation):
self.latitude = latitude
self.longitude = longitude
self.elevation = elevation
def __repr__(self):
return '<Geolocation %s, %s>' % (self.latitude, self.longitude)
class Pin(db.Model):
__tablename__ = "pin"
id = db.Column(db.Integer, primary_key=True)
geolocation_id = db.Column(db.Integer, db.ForeignKey('geolocation.id')) # True one to one relationship (Implicit child)
def __init__(self, geolocation_id):
self.geolocation_id = geolocation_id
def __repr__(self):
return '<Pin Object %s>' % id(self) # Instance id merely useful to differentiate instances.
class User(Pin):
#id = db.Column(db.Integer, primary_key=True)
pin_id = db.Column(db.Integer, db.ForeignKey('pin.id'), primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password_hash = db.Column(db.String(120), nullable=False)
salt = db.Column(db.String(120), nullable=False)
# Relationships
#posts = db.relationship('Post', backref=db.backref('user'), lazy='dynamic') #One User to many Postings.
def __init__(self, username, password_hash, salt, geolocation_id):
super(Pin, self).__init__(self, geolocation_id)
self.username = username
self.password_hash = password_hash
self.salt = salt
def __repr__(self):
return '<User %r>' % self.username
I'm confused about how to set up id's and relationships with subclasses in SQLAlchemy (I happen to be using Flask-SQLAlchemy). My general design is to have the superclass Pin be a high level representation of anything that has a geolocation (i.e. a User, a Place, etc.).
There is a one to one relationship between a Pin and Geolocation object so a Geolocation does not contain the location of two Users (or a User and a Place) simultaneously for example. Now I want to subclass Pin to create the User class. A User object should have a name, password_hash, salt and I also want to be able to lookup the Geolocation of the User via userObj.geolocation. However, I later want to make a class Place which also subclasses Pin and I should be able to lookup the geolocation of a Place via placeObj.geolocation . Given a geolocation object, I should be able to use geolocationObj.pin to lookup the User/Place/etc. that the geolocation object corresponds to. The whole reason I introduced the superclass Pin was to ensure that there was a pure one to one relationship between Pin and Geolocation objects rather than having a Geolocation be associated with either a User or a Person which would require the Geolocation table to have user_id and place_id columns, one of which would always be null.
I was expecting every User to automatically have a .geolocation property, via the parent Pin class, which referred to a Geolocation but it seems like SQLAlchemy does not do this. How can I make subclassing relationships work to accomplish my goal of having User and Place and potentially other classes subclass Pin, have each of those classes have a geolocation property via Pin, and have a one to one relationship between a Pin and a Geolocation?