Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alembic does not make composite primary key

I had a SQLAlchemy model like -

class UserFavPlace(db.Model):
    # This model stores the feedback from the user whether he has
    # faved a place or not
    __tablename__ = u'user_fav_places'

    id = db.Column(db.Integer, primary_key = True)
    public_place_id = db.Column(db.Integer, db.ForeignKey(u'public_places.id'))
    user_id = db.Column(db.Integer, db.ForeignKey(u'users.user_id'))
    fav = db.Column(db.Boolean)
    updated_time = db.Column(db.DateTime)

    place = relationship(u'PublicPlace', backref = u'user_fav_places')
    user = relationship(u'User', backref = u'user_fav_places')

And then I changed this model to the following -

class UserFavPlace(db.Model):
    # This model stores the feedback from the user whether he has
    # faved a place or not
    __tablename__ = u'user_fav_places'

    public_place_id = db.Column(db.Integer, db.ForeignKey(u'public_places.id'),
            primary_key = True)
    user_id = db.Column(db.Integer, db.ForeignKey(u'users.user_id'),
            primary_key = True)
    fav = db.Column(db.Boolean)
    updated_time = db.Column(db.DateTime)

    place = relationship(u'PublicPlace', backref = u'user_fav_places')
    user = relationship(u'User', backref = u'user_fav_places')

However, Alembic is not generating the correct upgrade and downgrade statements. Seems like it is not adding the newly introduced primary key constraints.

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('user_fav_places', 'id')
    ### end Alembic commands ###


def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.add_column('user_fav_places', sa.Column('id', mysql.INTEGER(display_width=11), nullable=False))
    ### end Alembic commands ###

I am not sure on how to add this.

like image 965
Siddharth Avatar asked Mar 10 '15 08:03

Siddharth


People also ask

How do you make a composite key?

A Composite Primary Key is created by combining two or more columns in a table that can be used to uniquely identify each row in the table when the columns are combined, but it does not guarantee uniqueness when taken individually, or it can also be understood as a primary key created by combining two or more ...

Can PRIMARY KEY and composite key be in same table?

So yes, a table can have a PRIMARY KEY on one column, and a composite UNIQUE INDEX or UNIQUE CONSTRAINT.

Can you have 3 primary keys?

Primary keys must contain UNIQUE values, and cannot contain NULL values. A table can have only ONE primary key; and in the table, this primary key can consist of single or multiple columns (fields).

How do I downgrade my alembic?

If you want to run to downgrade() of a version, you will need to run alembic downgrade the-version-before-it , which mean it will revert to the version after the version that you want to downgrade. Which is the version before the version that we want to revert.


1 Answers

I find the autogeneration to be pretty bad about detecting primary/foreign key changes. Which is okay, usually you want to customize those anyway.

I haven't created composite primary keys, but it looks like this should work based on the doc:

http://alembic.zzzcomputing.com/en/latest/ops.html#alembic.operations.Operations.create_primary_key

op.create_primary_key(
        "pk_user_fav_places", "user_fav_places",
        ["public_place_id", "user_id"]
    )

However, you might run into a different problem, which I wrote up here: Adding primary key to existing MySQL table in alembic

This might have been fixed in more recent versions of alembic, but it may not let you create primary keys on existing tables (see the answer to above for why). If that happens, you can just craft the SQL yourself and run it with op.execute.

Hope that helps!

like image 199
Rachel Sanders Avatar answered Sep 21 '22 02:09

Rachel Sanders