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

Refs #6148 -- Meta table api #6162

wants to merge 9 commits into from


Copy link

akaariai commented Feb 19, 2016

Add Model._meta.table_cls attribute to represent table-like objects. Add schema qualified table support.

Continuation from #5278.


  • PostgreSQL support (we are nearly there)
  • tests in Django's test suite (test project attached)
  • docs
  • introspection support as needed by migrations (get_constraints(), table_names())
  • Nice failures for cases where schemas are used for Oracle, MySQL and SQLite
  • Remove a couple of TODOs and temporary asserts

Not going to be implemented in this PR:

  • MySQL support (in mysql schemas are a synonym for database. This is going to cause problems for testing, where production and test database schemas would conflict)
  • SQLite support (no schemas on SQLite)
  • Oracle support (we use Oracle schemas to differentiate between test and production, so similar problems as with MySQL are preventing support for Oracle in initial implementation)
  • Inspectdb support
  • Dynamic schemas (same model on multiple schemas will not be supported by Django)
  • Ability to configure default schema for project or apps

Test project for PostgreSQL here:

akaariai added 7 commits Sep 8, 2015
The feature allows for using schema qualified table names. There is no
migrations support for this yet, though. With migrations support #6148
would be fixed.

Another compelling (but untested) use case is view-like features. That
is, you could have models that query from a subquery. The essence is
the ability to plug in raw SQL in to normal ORM queries. Something

class Book(models.Model):
    title = models.TextField()

class Author(models.Model):
    age = models.IntegerField()
    book = models.ManyToManyField(Book)

class AverageAuthorAge(models.Model):
    book = models.OneToOneField(Book, primary_key=True)
    average_author_age = models.DecimalField()

    class Meta:
        table_cls = View(
    'select avg(age) as average_author_age, book_authors.book_id '
    '  from author inner join book_authors on '
    ' = book_authors.author_id '
    ' group by book_id')

Currently, if using a table_cls in model.Meta, the behavior of
migrations framework is undefined.

This comment has been minimized.

Copy link
Member Author

akaariai commented Feb 19, 2016

There isn't that much complex work left (the hardest part is likely the inspectdb changes). I guess there is about a week's worth of work left. The problem is that I don't have that much time available these days, so process is slow.

@akaariai akaariai changed the title Meta table api Refs #6148 -- Meta table api Feb 19, 2016

This comment has been minimized.

Copy link
Member Author

akaariai commented Feb 20, 2016

I recall an idea brought up for the problem that Oracle and MySQL schema conflicts between production and testing. The idea was something like database setting 'test_schema_mapping'. This maps production schema name to testing schema name. If you use identity mapping, then testing and production uses same schema names. In that case the user is responsible for any problems that might cause.

I'm not going to implement that for the initial merge to Django unless requested. I'd like to keep this patch as simple as possible as I don't have too much time. This means the initial merge will have only PostgreSQL support.


This comment has been minimized.

Copy link

c7h commented May 25, 2016

Are there any news? What needs to be done? I would like to help.


This comment has been minimized.

Copy link

timgraham commented Jul 15, 2016

Anssi, please reopen if you pick up work on this again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
3 participants
You can’t perform that action at this time.