Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relation "migratehistory" already exists #51

Closed
Tumetsu opened this issue Jul 12, 2017 · 3 comments
Closed

Relation "migratehistory" already exists #51

Tumetsu opened this issue Jul 12, 2017 · 3 comments

Comments

@Tumetsu
Copy link

Tumetsu commented Jul 12, 2017

When I try to run all unapplied migrations, I get the following error:

peewee.ProgrammingError: relation "migratehistory" already exists

My python script to run all migrations:

db_connection.init_database()
db_connection.connect()
database = db_connection.get_database()

router = Router(database)

# Run all unapplied migrations
router.run()

After quick investigation to the source of peewee_migrate I found this from BaseRouter:

    @cached_property
    def model(self):
        """Initialize and cache MigrationHistory model."""
        MigrateHistory._meta.database = self.database
        MigrateHistory._meta.db_table = self.migrate_table
        MigrateHistory.create_table(True)
        return MigrateHistory

Looks like it tries to create the table always because of the last line before return which then fails if I have already migrated something to the db and the table exists. Why is that? Am I using this wrong somehow?

My peewee and peewee_migrate versions:

peewee==2.8.5
peewee-migrate==0.12.3

Using Python 3.5

And full stack trace:

Traceback (most recent call last):
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee.py", line 3768, in execute_sql
    cursor.execute(sql, params or ())
psycopg2.ProgrammingError: relation "migratehistory" already exists


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/tuomas/Code/KarjalaProject/karelian-db/tasks/migrate.py", line 12, in <module>
    router.run()
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee_migrate/router.py", line 163, in run
    diff = self.diff
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee_migrate/router.py", line 57, in diff
    done = set(self.done)
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee_migrate/router.py", line 52, in done
    return [mm.name for mm in self.model.select()]
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/cached_property.py", line 26, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee_migrate/router.py", line 42, in model
    MigrateHistory.create_table(True)
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee.py", line 4975, in create_table
    db.create_table(cls)
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee.py", line 3852, in create_table
    return self.execute_sql(*qc.create_table(model_class, safe))
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee.py", line 3775, in execute_sql
    self.commit()
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee.py", line 3598, in __exit__
    reraise(new_type, new_type(*exc_args), traceback)
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee.py", line 135, in reraise
    raise value.with_traceback(tb)
  File "/home/tuomas/Code/KarjalaProject/karelian-db/karelian-db_venv/lib/python3.5/site-packages/peewee.py", line 3768, in execute_sql
    cursor.execute(sql, params or ())
peewee.ProgrammingError: relation "migratehistory" already exists
@Tumetsu
Copy link
Author

Tumetsu commented Jul 12, 2017

After some tinkering I found that the following modification seems to work:

@cached_property
    def model(self):
        """Initialize and cache MigrationHistory model."""
        MigrateHistory._meta.database = self.database
        MigrateHistory._meta.db_table = self.migrate_table
        self.database.create_table(MigrateHistory, safe=True)
        return MigrateHistory

and I posted an issue about it to peewee's repo: coleifer/peewee#1314

@Tumetsu
Copy link
Author

Tumetsu commented Jul 12, 2017

Ok, I found the issue. Problem was that I have multiple schemas in my database and at the moment peewee_migrate seems to add migratehistorytable to first schema, in my case to schema extensions. Now since 'MigrateHistorydoes not specify meta optionschema peewee's table_exists function fails because its implementation requires schema to be set:

@classmethod
    def table_exists(cls):
        kwargs = {}
        if cls._meta.schema:
            kwargs['schema'] = cls._meta.schema
        return cls._meta.db_table in cls._meta.database.get_tables(**kwargs)

So for now the solution is to add following to the MigrateHistory model:

    class Meta:
        schema = 'schema_name'

This is a bit dirty however. Would it be possible to somehow configure MigrateHistorymodel to pass it the schema option?

@klen
Copy link
Owner

klen commented Sep 6, 2017

Hello @Tumetsu,

Good point. Sorry for the late response, but I've added schema param to Router. And now the option is configurable.

@klen klen closed this as completed Sep 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants