Python SQLAlchemy子类/继承关系 类地理位置(db.Model): __tablename_=“地理位置” id=db.Column(db.Integer,主键=True) 纬度=分贝列(分贝浮点) 经度=分贝列(分贝浮点) 标高=分贝柱(分贝浮标)#米 #关系 pin=db.relationship('pin',uselist=False,backref=“geolocation”) 定义初始(自身、纬度、经度、海拔): 自纬度=纬度 self.longitude=经度 自升高度=自升高度 定义报告(自我): 返回“”%(自纬度、自经度) 类别Pin(db.Model): __tablename_=“pin” id=db.Column(db.Integer,主键=True) geolocation_id=db.Column(db.Integer,db.ForeignKey('geolocation.id'))#真一对一关系(隐式子项) 定义初始(自我,地理位置id): self.geolocation\u id=geolocation\u id 定义报告(自我): 返回“%id(self)#实例id仅用于区分实例。 类别用户(Pin): #id=db.Column(db.Integer,主键=True) pin_id=db.Column(db.Integer,db.ForeignKey('pin.id'),primary_key=True) username=db.Column(db.String(80),unique=True,nullable=False) 密码\u hash=db.Column(db.String(120),nullable=False) salt=db.Column(db.String(120),nullable=False) #关系 #posts=db.relationship('Post',backref=db.backref('user'),lazy='dynamic')#一个用户对多个帖子。 定义初始化(self、用户名、密码\u散列、salt、地理位置\u id): 超级(Pin,self)。\uuuuu初始(self,geolocation\u id) self.username=用户名 self.password\u hash=密码\u hash self.salt=盐 定义报告(自我): 返回“%self.username”
我对如何在SQLAlchemy中设置id以及与子类的关系感到困惑(我碰巧在使用Flask SQLAlchemy)。我的总体设计是让超类Pin成为具有地理位置(即用户、地点等)的任何事物的高级表示 Pin和地理定位对象之间存在一对一的关系,因此地理定位不会同时包含两个用户(或一个用户和一个地点)的位置。现在,我想将Pin子类化以创建用户类。用户对象应该有名称、密码、哈希、salt,我还希望能够通过Python SQLAlchemy子类/继承关系 类地理位置(db.Model): __tablename_=“地理位置” id=db.Column(db.Integer,主键=True) 纬度=分贝列(分贝浮点) 经度=分贝列(分贝浮点) 标高=分贝柱(分贝浮标)#米 #关系 pin=db.relationship('pin',uselist=False,backref=“geolocation”) 定义初始(自身、纬度、经度、海拔): 自纬度=纬度 self.longitude=经度 自升高度=自升高度 定义报告(自我): 返回“”%(自纬度、自经度) 类别Pin(db.Model): __tablename_=“pin” id=db.Column(db.Integer,主键=True) geolocation_id=db.Column(db.Integer,db.ForeignKey('geolocation.id'))#真一对一关系(隐式子项) 定义初始(自我,地理位置id): self.geolocation\u id=geolocation\u id 定义报告(自我): 返回“%id(self)#实例id仅用于区分实例。 类别用户(Pin): #id=db.Column(db.Integer,主键=True) pin_id=db.Column(db.Integer,db.ForeignKey('pin.id'),primary_key=True) username=db.Column(db.String(80),unique=True,nullable=False) 密码\u hash=db.Column(db.String(120),nullable=False) salt=db.Column(db.String(120),nullable=False) #关系 #posts=db.relationship('Post',backref=db.backref('user'),lazy='dynamic')#一个用户对多个帖子。 定义初始化(self、用户名、密码\u散列、salt、地理位置\u id): 超级(Pin,self)。\uuuuu初始(self,geolocation\u id) self.username=用户名 self.password\u hash=密码\u hash self.salt=盐 定义报告(自我): 返回“%self.username”,python,sql,flask,sqlalchemy,flask-sqlalchemy,Python,Sql,Flask,Sqlalchemy,Flask Sqlalchemy,我对如何在SQLAlchemy中设置id以及与子类的关系感到困惑(我碰巧在使用Flask SQLAlchemy)。我的总体设计是让超类Pin成为具有地理位置(即用户、地点等)的任何事物的高级表示 Pin和地理定位对象之间存在一对一的关系,因此地理定位不会同时包含两个用户(或一个用户和一个地点)的位置。现在,我想将Pin子类化以创建用户类。用户对象应该有名称、密码、哈希、salt,我还希望能够通过userObj.Geolocation查找用户的地理位置。然而,我后来想创建一个类Place,它也将P
userObj.Geolocation
查找用户的地理位置。然而,我后来想创建一个类Place,它也将Pin子类化,并且我应该能够通过placeObj.geolocation
查找位置的地理位置。给定一个geolocation对象,我应该能够使用geolocationObj.pin
查找geolocation对象对应的用户/地点/等。我引入超类Pin的全部原因是为了确保Pin和地理位置对象之间存在纯粹的一对一关系,而不是让地理位置与用户或个人相关联,这将要求地理位置表具有User\u id
和place\u id
列,其中一个总是空的
我希望每个用户都能通过父Pin类自动拥有
.geolocation
属性,该类引用了一个geolocation,但SQLAlchemy似乎没有做到这一点。我如何使子类化关系发挥作用,以实现我的目标,即让User和Place以及潜在的其他类子类Pin,让这些类中的每个类都通过Pin具有地理位置属性,并且在Pin和地理位置之间具有一对一的关系?以下是SQLAlchemy中用于和的文档
我相信您会想要联接表继承风格,这意味着父类链中的每个类都有自己的表,表中的列是唯一的。基本上,您需要在
pin
表中添加一个鉴别器列来表示每个pin的子类类型,并在类中添加一些双下划线属性来描述SQLAlchemy的继承配置。我提出的解决方案。这是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
类地理位置(基本):
__tablename_=“地理位置”
id=列(整数,主键=True)
纬度=列(浮动)
经度=列(浮动)
标高=立柱(浮标)#米
#关系
person=关系('Pin',uselist=False,backref=“geolocation”)
定义初始(自身、纬度、经度、海拔):
自纬度=纬度
self.longitude=经度
自升高度=自升高度
定义报告(自我):
返回“”%(自纬度、自经度)
类别针(底座):
__tablename_uu='pin'
id=列(整数,主键=True)
geolocation_id=Column(整数,ForeignKey('geolocation.id'),unique=True,nullable=False)#True一对一关系(隐式子项)
类型=列('type',字符串(50))#鉴别器
__mapper_args_uu={'polymorphic_on':type}
定义初始(自我,地理位置id):
self.geolocation\u id=geolocation\u id
类别用户(Pin):
__tablename_uu='user'
id=列(整数,外键('pin.id'),主键=True)
__mapper_args_uu={'polymorphic_identity':'user',
“继承条件”:(id==Pin.id)}
用户标识=列(整数,自动递增=真,主键=真,唯一=真)
username=Column(字符串(80),unique=True)
密码\u散列=列(字符串(120))
salt=列(字符串(120))
posts=relationship('Posting',primaryjoin=“(User.User\u id==Posting.User\u id)”,backref=backref('User'),lazy='dynamic')#一个用户对多个帖子。
定义初始化(self、用户名、密码\u散列、salt、geo\u id):
超级(用户,自我)。\uuuuu初始化\uuuuuuuu(地理id)
self.username=用户名
self.password\u hash=密码\u hash
self.salt=盐
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)