4

私はユーザーよりもはるかに多くの人がいる小さなデータベースを開発しているので、現在次のモデルがあります。

class Person(db.Model):
  __tablename__ = 'people'
  id       = db.Column(db.Integer, primary_key = True)
  forename = db.Column(db.String(64))
  surname  = db.Column(db.String(64))

  memberships = db.relationship('Membership', backref='person')

  @property
  def name(self):
    return self.forename + ' ' + self.surname

  def __repr__(self):
    return '<Person %r %r>' % (self.forename, self.surname)

class User(Person):
  __tablename__ = 'users'
  id       = db.Column(db.Integer, db.ForeignKey('people.id'), primary_key = True)
  email    = db.Column(db.String(120), index = True, unique = True)
  role     = db.Column(db.SmallInteger, default = ROLE_USER)

  salt     = db.Column(db.BINARY(8))
  password = db.Column(db.BINARY(20))

  def __repr__(self):
    return '<User %r>' % (self.email)

ユーザーを作成すると、ユーザーも保存されるという点で、非常にうまく機能しています。問題は、Personがデータベースにすでに存在するときにUserを作成することです。

私は以下を試しました:

>>> p = models.Person.query.get(3)
>>> u = models.User(id=p.id, email="example@example.com")
>>> u.set_password('password')
>>> db.session.add(u)
>>> db.session.commit()
Traceback
...
sqlalchemy.exc.IntegrityError: (IntegrityError) PRIMARY KEY must be unique u'INSERT INTO people (id, forename, surname) VALUES (?, ?, ?)' (3, None, None)

私は何が間違っているのですか?人からユーザーを作成する方法はありますか?

4

1 に答える 1

1

Michael Bayerのアドバイスにより、ポリモーフィズムのデザインを変更し、代わりにコンポジションを使用しました。コードは次のようになります...

class Person(db.Model):
  __tablename__ = 'people'
  id       = db.Column(db.Integer, primary_key = True)
  forename = db.Column(db.String(64))
  surname  = db.Column(db.String(64))

  memberships = db.relationship('Membership', backref='person')

  @property
  def name(self):
    return self.forename + ' ' + self.surname

  def __repr__(self):
    return '<Person %r %r>' % (self.forename, self.surname)

class User(db.Model):
  __tablename__ = 'users'
  id       = db.Column(db.Integer, db.ForeignKey('people.id'), primary_key = True)
  email    = db.Column(db.String(120), index = True, unique = True)
  role     = db.Column(db.SmallInteger, default = ROLE_USER)

  salt     = db.Column(db.BINARY(8))
  password = db.Column(db.BINARY(20))

  person   = db.relationship('Person')

質問のセッションと同様のセッションは次のようになります...

>>> p = models.Person.query.get(3)
>>> u = models.User(person=p, email="example@example.com")
>>> u.set_password('password')
>>> db.session.add(u)
>>> db.session.commit()
>>>
于 2012-10-29T21:54:17.810 に答える