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 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

我对如何在SQLAlchemy中设置id以及与子类的关系感到困惑(我碰巧在使用Flask SQLAlchemy)。我的总体设计是让超类Pin成为具有地理位置(即用户、地点等)的任何事物的高级表示

Pin和地理定位对象之间存在一对一的关系,因此地理定位不会同时包含两个用户(或一个用户和一个地点)的位置。现在,我想将Pin子类化以创建用户类。用户对象应该有名称、密码、哈希、salt,我还希望能够通过
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)