【问题标题】:Create a child object based on a parent one基于父对象创建子对象
【发布时间】:2019-10-14 23:09:51
【问题描述】:

我正在开发一个数据库,您首先注册为普通的User,然后成为Driver。我想基于现有的User 对象在 SQL-Alchemy 中创建一个Driver 对象。我怎样才能做到这一点?

假设User 表已经有一个ID=3 的用户。现在我们想添加一个基于该用户的Driver

这是我使用的类:

# Base class
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(MAX_NAME_LENGTH), nullable=False)
    last_name = db.Column(db.String(MAX_SURNAME_LENGTH), nullable=False)
    email = db.Column(db.String(MAX_EMAIL_LENGTH), nullable=False, unique=True)


# Child class
class Driver(User):
    id = db.Column(db.Integer, db.ForeignKey(User.__tablename__ + '.id'), primary_key=True)
    photo_url= db.Column(db.String(MAX_URL_LENGTH), nullable=False)
    # ...
# we can easily add a new User
user = User(first_name='Martin', last_name='Smith', email='m.smith@gmail.com')
db.session.add(user)
db.session.commit()
# But this code will create a new user and assign it to that driver instance!
# driver = Driver(# Will require fields of both User and Driver class #)

我希望找到一些方法来获取父对象并使用子对象的属性对其进行扩展。比如:

user_from_db = db.session.query(User).filter_by(User.id == 3).first()
driver = Driver(photo_url='/your_url/', based_on=user_from_db)
# And now driver has all properties of 'user_from_db'
# Furthermore, SQL-Alchemy would create a row only in `Driver` table

如何使用 SQL-Alchemy 继承来实现这一点?

【问题讨论】:

标签: sqlalchemy flask-sqlalchemy


【解决方案1】:

首先,我建议进行以下更改:
autoincrement 字段是将分配 id 的任务留给数据库。
对于所有关系(OneToMany、ManyToMany 或 OneToOne),您需要在父类中指定一个 db.relationship。 Read this
并且__tablename__ 是可选的,但有时如果没有分配,flask 会抛出错误。

# Base class
class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    first_name = db.Column(db.String(MAX_NAME_LENGTH), nullable=False)
    last_name = db.Column(db.String(MAX_SURNAME_LENGTH), nullable=False)
    email = db.Column(db.String(MAX_EMAIL_LENGTH), nullable=False, unique=True)
    driver = db.relationship('Driver', backref='driver', lazy=True)


# Child class
class Driver(db.Model):
    __tablename__ = 'driver'
    id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    photo_url= db.Column(db.String(MAX_URL_LENGTH), nullable=False)
    # ...
user = User(first_name='Martin', last_name='Smith', email='m.smith@gmail.com')
db.session.add(user) # first we create a user and add him to the current session
db.session.flush() # here we says that db.session.add(user) is a pending transaction. More info [here][1]
driver = Driver(id=user.id, photo_url='/your_url/')
# and we pass as driver id the id of user previously created
db.session.add(driver) # add driver to current session
db.session.commit() # commits those changes to the database.

【讨论】:

  • 感谢您的回复!那么,您建议我在这种情况下使用relationship 而不是模型继承?我也想过这个。但是有可能解决我的 ORM 继承问题吗?还是我对 ORM 继承的使用有一些误解?
  • 我并不是说“关系”比继承更好,因为我不知道每个人的优缺点。也许可以通过继承来解决它,但我想出了一个使用外键作为主键的解决方案,并尊重你提出的一切。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多