【问题标题】:Composite Keys in SqlalchemySqlalchemy 中的复合键
【发布时间】:2012-06-23 19:22:45
【问题描述】:

我正在使用 flask-sqlalchemy 构建一个 webapp,我有以下模型:

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)
    candidates = db.relationship('Candidate', backref='post', lazy='dynamic')

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "<Post %r>" % self.name

class Candidate(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), primary_key=True)
    post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
    hostel = db.Column(db.String(80))
    yes_no = db.Column(db.Boolean)
    #votes = db.relationship('Vote', backref='vote', lazy="dynamic")

    def __init__(self, name, hostel, post_id, yes_no):
        self.name = name
        self.hostel = hostel
        self.post_id = post_id
        self.yes_no = yes_no

    def __repr__(self):
        return "<Candidate: %r, Post: %r>" % (self.name, self.post.name)

在数据库设计方面我完全是菜鸟,所以我非常感谢一些关于我有的一些基本查询的指针

  • id 列是否必要?我见过的大多数教程都将其作为一列(特别是主键)。我可以没有它吗?特别是在我有另一个主键的情况下?

  • 如果 post_id 是外键,我如何对 Candidate#Name 和 Candidate#post_id 列设置复合键约束。

  • 如何“刷新”我的数据库。在对模型进行更改后,如何确保这些更改反映在实际表中?我需要手动drop_allcreate_all 吗?

  • 最后,sqlalchemy 文档是否也适用于flask-sqlalchemy

【问题讨论】:

  • 你可能想把这些问题分开;在一个问题中发布多个问题时,您使人们更难为您提供答案。所有sqlalchemy 文档也适用于flask-sqlalchemy

标签: python sqlalchemy primary-key


【解决方案1】:

id 列是必需的吗?我见过的大多数教程都将其作为一列(特别是主键)。我可以没有它吗?特别是在我有另一个主键的情况下?

对于 post 表,是的。对于另一个,没有。有些人可能会争辩说,由于 name 是唯一的,因此将其设为主键,但这意味着使用名称 anywhere 您需要引用该帖子,这意味着更多空间(名称长度与 int 的对比) (不一定是问题)并考虑“如果候选人名称发生变化怎么办?”。但是,您当然不需要两者。

鉴于 post_id 是外键,我如何对 Candidate#Name 和 Candidate#post_id 列进行复合键约束。

你是怎么做的,每个帖子都分配给一个帖子:

candidates = db.relationship('Candidate', backref='post', lazy='dynamic')

因此,该字段不应称为 candidates 而是 candidate 才有意义。

为了回答你的问题,我将引用the docs

在约束/索引中指定多个列或指定一个 显式名称,使用 UniqueConstraint 或 Index 构造 明确的。

您需要将此添加到您的模型定义中:

__table_args__ = (
        UniqueConstraint("id", "candidate_id"),
    )

虽然我觉得这里没用(为什么需要它?如果 id 是唯一的(主键),那么包含它的任何其他组合都是唯一的)...

如何“刷新”我的数据库。在我对模型进行更改后, 如何确保这些更改反映在实际表格中? 我需要手动 drop_all 和 create_all 吗?

您需要commit您对数据库的更改。来自flask-sqlalchemy's documentation

db.session.add(post)
db.session.commit()

最后,sqlalchemy 文档是否适用于 flask-sqlalchemy 好吗?

注意这是我自己发现的,没有“官方”来源,只是通过阅读 flask-sqlalchemy 的来源。

是的,不同的是您访问模型、会话和引擎的方式以及... 例如,在 sqlalchemy 中:

from sqlalchemy.orm import sessionmaker
Session = sessionmaker()
session = session()
session.commit()

在flask-sqlalchemy中:

db.session.commit()

对于“模型”:

# In sqlalchemy
Base = declarative_base()
class Post(Base):
    # ...

# In flask-sqlalchemy
class Post(db.Model):
    # ...

等等……

不管怎样,你用 sqlalchemy 的方式做的事情,你做一次,flask-sqlalchemy 会在后台帮你做。

希望对您有所帮助:)(这不仅仅是关于 sqlalchemy 中复合键的一个问题......)

【讨论】:

  • soooo...如何添加复合键?
  • @PiotrKamoda 如果您需要复合主键,只需将 primary_key=True 设置为所有主键字段。或者在__table_args__ 中使用类似于UniqueConstraint("id", "candidate_id") 的内容。您甚至可以在表 args 中指定更复杂的主键。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-22
  • 2018-05-30
  • 2015-05-28
  • 2015-02-02
  • 1970-01-01
相关资源
最近更新 更多