dgh*_*dgh 4 python sql sqlalchemy flask flask-sqlalchemy
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
Run Code Online (Sandbox Code Playgroud)
我对如何在SQLAlchemy中设置id和与子类的关系感到困惑(我碰巧使用的是Flask-SQLAlchemy).我的一般设计是让超类Pin成为具有地理定位的任何东西的高级表示(即用户,地点等).
Pin和Geolocation对象之间存在一对一的关系,因此Geolocation不会同时包含两个用户(或用户和地点)的位置.现在我想子类Pin来创建User类.User对象应该有一个名称,password_hash,salt,我也希望能够通过查找用户的Geolocation userObj.geolocation.但是,我后来想要创建一个类Place,它也是子类Pin,我应该能够查找Place的地理位置placeObj.geolocation.给定一个地理定位对象,我应该可以geolocationObj.pin用来查找User/Place/etc.地理定位对象对应的.我引入超类Pin的全部原因是为了确保Pin和Geolocation对象之间存在纯粹的一对一关系,而不是将Geolocation与要求Geolocation表user_id和place_id列的User或Person相关联,其中一个永远是null.
我希望每个用户都可以.geolocation通过父Pin类自动拥有一个属性,它引用了一个Geolocation,但似乎SQLAlchemy没有这样做.如何使子类关系工作以实现我的目标,即拥有User和Place以及可能的其他类子类Pin,让每个类通过Pin具有地理定位属性,并在Pin和Geolocation之间建立一对一的关系?
我提出的解决方案.这是在声明式样式中使用Join继承在SQLAlchemy中进行子类化的完整示例.
class Geolocation(Base):
__tablename__ = "geolocation"
id = Column(Integer, primary_key=True)
latitude = Column(Float)
longitude = Column(Float)
elevation = Column(Float) # Meters
# Relationships
person = 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(Base):
__tablename__ = 'pin'
id = Column(Integer, primary_key=True)
geolocation_id = Column(Integer, ForeignKey('geolocation.id'), unique=True, nullable=False) # True one to one relationship (Implicit child)
type = Column('type', String(50)) # discriminator
__mapper_args__ = {'polymorphic_on': type}
def __init__(self, geolocation_id):
self.geolocation_id = geolocation_id
class User(Pin):
__tablename__ = 'user'
id = Column(Integer, ForeignKey('pin.id'), primary_key=True)
__mapper_args__ = {'polymorphic_identity': 'user',
'inherit_condition': (id == Pin.id)}
user_id = Column(Integer, autoincrement=True, primary_key=True, unique=True)
username = Column(String(80), unique=True)
password_hash = Column(String(120))
salt = Column(String(120))
posts = relationship('Posting', primaryjoin="(User.user_id==Posting.user_id)", backref=backref('user'), lazy='dynamic') #One User to many Postings.
def __init__(self, username, password_hash, salt, geo_id):
super(User, self).__init__(geo_id)
self.username = username
self.password_hash = password_hash
self.salt = salt
def __repr__(self):
return '<User %s>' % (self.username)
class Posting(Pin):
__tablename__ = 'posting'
id = Column(Integer, ForeignKey('pin.id'), primary_key=True)
__mapper_args__ = {'polymorphic_identity': 'posting',
'inherit_condition': (id == Pin.id)}
posting_id = Column(Integer, autoincrement=True, primary_key=True, unique=True)
creation_time = Column(DateTime)
expiration_time = Column(DateTime)
user_id = Column(Integer, ForeignKey('user.user_id')) # One User to many Postings
def __init__(self, creation_time, expiration_time, user_id, geo_id):
super(Posting, self).__init__(geo_id)
# For now, require creation time to be passed in. May make this default to current time.
self.creation_time = creation_time
self.expiration_time = expiration_time
self.user_id = user_id
def __repr__(self):
#TODO come up with a better representation
return '<Post %s>' % (self.creation_time)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5955 次 |
| 最近记录: |