klen / peewee_migrate

Simple migration engine for Peewee

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IntegrityError: Cannot add foreign key constraint

dmitrykiselev27 opened this issue · comments

Migration generated using pw_migrate create --auto models --database mysql://user:pass@localhost/test --directory migrations test fails to apply with the error peewee.IntegrityError: (1215, 'Cannot add foreign key constraint').

Database: MySQL

mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+-------------------------+
| Variable_name           | Value                   |
+-------------------------+-------------------------+
| innodb_version          | 5.7.22                  |
| protocol_version        | 10                      |
| slave_type_conversions  |                         |
| tls_version             | TLSv1,TLSv1.1           |
| version                 | 5.7.22-0ubuntu0.16.04.1 |
| version_comment         | (Ubuntu)                |
| version_compile_machine | x86_64                  |
| version_compile_os      | Linux                   |
+-------------------------+-------------------------+

models.py

class BaseModel(Model):
    class Meta:
        database = database


class Model1(BaseModel):
    id = BigAutoField()

    class Meta:
        table_name = 'tb_name1'


class Model2(BaseModel):
    id = BigAutoField()
    site = ForeignKeyField(column_name='model1_id', field='id', model=Model1, null=True)

    class Meta:
        table_name = 'tb_name2'

migrations/001_test.py

import datetime as dt
import peewee as pw

try:
    import playhouse.postgres_ext as pw_pext
except ImportError:
    pass


def migrate(migrator, database, fake=False, **kwargs):
    """Write your migrations here."""

    @migrator.create_model
    class BaseModel(pw.Model):
        id = pw.AutoField()

        class Meta:
            table_name = "basemodel"

    @migrator.create_model
    class Model1(pw.Model):
        id = pw.BigAutoField()

        class Meta:
            table_name = "tb_name1"

    @migrator.create_model
    class Model2(pw.Model):
        id = pw.BigAutoField()
        site = pw.ForeignKeyField(backref='model2_set', column_name='model1_id', field='id', model=migrator.orm['tb_name1'], null=True)

        class Meta:
            table_name = "tb_name2"



def rollback(migrator, database, fake=False, **kwargs):
    """Write your rollback migrations here."""

    migrator.remove_model('tb_name2')

    migrator.remove_model('tb_name1')

    migrator.remove_model('basemodel')

Output of SHOW ENGINE INNODB STATUS;:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
2018-05-30 10:27:24 0x7fdfd835c700 Error in foreign key constraint of table bench_test/tb_name2:
FOREIGN KEY (`model1_id`) REFERENCES `tb_name1` (`id`)):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-foreign-key-constraints.html for correct foreign key definition.