Составные ключи в Sqlalchemy

Я использую 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)

я полностью noob, когда дело доходит до проектирования баз данных, поэтому я буду очень признателен за несколько указателей на некоторые фундаментальные запросы, которые у меня есть

  • - это

1 ответов


необходим ли столбец id? Большинство учебников, которые я видел, имеют это как столбец (в частности, первичный ключ). Могу ли я обойтись без этого? Особенно в тех случаях, когда у меня есть еще один первичный ключ?

для таблицы post, да. Для другого-нет. Некоторые могут утверждать, что, поскольку имя уникально, сделайте его первичным ключом, но это будет означать использование имени в любом месте вам нужно ссылаться на этот пост, что означает больше места (длина имени против int) (не обязательно проблема) и подумайте о том, "что, если имя кандидата изменится?". Тем не менее, вам определенно не нужны оба.

как я могу иметь составное ограничение ключа для столбцов Candidate#Name и Candidate#post_id, учитывая, что post_id является внешним ключом.

как вы это делаете, каждая должность назначается на одну должность:

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

Итак, поле не должно называться candidates но candidate смысл.

для ответить на ваш вопрос, я процитирую из документы:

чтобы указать несколько столбцов в ограничении / индексе или указать явное имя, используйте конструкции UniqueConstraint или Index явно.

вам нужно будет добавить это в определение модели:

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

хотя я думаю, что это бесполезно здесь (зачем вам это нужно? если id уникален(первичный ключ), то любая другая комбинация, содержащая его, будет уникальный.)..

как я могу "обновить" базу данных. После того, как я внес изменения в модель, как я могу убедиться, что эти изменения отражены в фактических таблицах? Нужно ли мне drop_all и create_all вручную?

вам нужно commit ваши изменения в базе данных. От колба-документация по sqlalchemy:

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

наконец, применяется ли документация sqlalchemy к flask-sqlalchemy как ну?

Примечание это то, что я узнал самостоятельно, без "официального" источника, просто прочитав источник flask-sqlalchemy.

Да, что отличается, так это способ доступа к модели и сессии и движку и ... Например, в sqlalchemy:

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

и в колбе-sqlalchemy:

db.session.commit()

и для "модели":

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

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

etc...

в любом случае, что вы делаете в SQLAlchemy, вы сделайте это один раз, и flask-sqlalchemy сделает это за вас в фоновом режиме.

надеюсь, это поможет :) (и это гораздо больше, чем один вопрос о составных ключах в sqlalchemy...)