django-tenant-schemas
django-tenant-schemas copied to clipboard
Using django-tenant-schemas doesn't apply my AUTH_USER_MODEL when running migrate_schema
Do I need to do something special to get django-tenant-schemas to work with my custom user model. I am following Django's directions to use AUTH_USER_MODEL. Before I started using django-tenant-schemas the migrations worked fine. Now they don't work with django-tenant-schemas.
When I run migrate_schemas I get the following error. The migration contains the same migration code that worked before I started using django-tenant-schemas.
=== Running migrate for schema public
Operations to perform:
Synchronize unmigrated apps: clients, tenant_schemas
Apply all migrations: admin, contenttypes, hub, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Creating table clients_client
Installing custom SQL...
Installing indexes...
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying hub.0001_initial... OK
Applying admin.0001_initial...Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/tenant_schemas/management/commands/migrate_schemas.py", line 24, in run_from_argv
super(MigrateSchemasCommand, self).run_from_argv(argv)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/tenant_schemas/management/commands/migrate_schemas.py", line 34, in handle
self.run_migrations(self.schema_name, settings.SHARED_APPS)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/tenant_schemas/management/commands/migrate_schemas.py", line 61, in run_migrations
command.execute(*self.args, **defaults)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 161, in handle
executor.migrate(targets, plan, fake=options.get("fake", False))
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/db/migrations/executor.py", line 68, in migrate
self.apply_migration(migration, fake=fake)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/db/migrations/executor.py", line 102, in apply_migration
migration.apply(project_state, schema_editor)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/db/backends/schema.py", line 82, in __exit__
self.execute(sql)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/db/backends/schema.py", line 102, in execute
cursor.execute(sql, params)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/db/backends/utils.py", line 81, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File ".../Projects/python-virtual-env/mlm27/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "hub_mlmuser" does not exist
I'm having the exact same issue when trying to use a custom user model with django-tenant-schemas. Have you perhaps found a solution in the meantime?
I maybe late to the party, but I ran into the same error which is not Django Nose specific. The error is related to the order of the installed apps in settings. If your using a custom model you need to make sure that the initial table created is your user model. You would get the same error without Django Nose when running migrations for the first time also.
@glynjackson I am late to this part too and believe that I might be seeing a similar issue (just posted an Issue, then saw this one). Can you expand on your comment slightly (maybe an example)? I am using
SHARED_APPS = (
'tenant_schemas', # mandatory
'customers', # you must list the app where your tenant model resides in
'django.contrib.contenttypes',
# everything below here is optional
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
)
TENANT_APPS = (
# The following Django contrib apps must be in TENANT_APPS
'django.contrib.contenttypes',
# your tenant-specific apps
'customauth',
)
INSTALLED_APPS = list(set(SHARED_APPS + TENANT_APPS))
where customauth contains the custom user.
Any ideas or help would be very greatly appreciated.
(@GlennV or @danolsen, did you guys get this working?)
As there are a number of ways to do custom user could you post a copy of your models file.
Here is my customauth/models.py file:
$ cat customauth/models.py
from django.db import models
# Create your models here.
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, date_of_birth, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(email,
password=password,
date_of_birth=date_of_birth
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
date_of_birth = models.DateField()
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['date_of_birth']
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
The error is:
$ python manage.py makemigrations customauth
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/commands/makemigrations.py", line 63, in handle
loader = MigrationLoader(None, ignore_no_migrations=True)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/db/migrations/loader.py", line 47, in __init__
self.build_graph()
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/db/migrations/loader.py", line 287, in build_graph
parent = self.check_key(parent, key[0])
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/db/migrations/loader.py", line 165, in check_key
raise ValueError("Dependency on unknown app: %s" % key[0])
ValueError: Dependency on unknown app: customauth
and the relevant part of the settings.py
TENANT_MODEL = "customers.Client"
AUTH_USER_MODEL = 'customauth.MyUser'
# Application definition
SHARED_APPS = (
'tenant_schemas', # mandatory
'customers', # you must list the app where your tenant model resides in
'django.contrib.contenttypes',
# everything below here is optional
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
)
TENANT_APPS = (
# The following Django contrib apps must be in TENANT_APPS
'django.contrib.contenttypes',
# your tenant-specific apps
'customauth',
)
INSTALLED_APPS = list(set(SHARED_APPS + TENANT_APPS))
(as an aside, @tomturner , I am using your version of django-tenant-schemas)
Have you tried putting the customauth model in the shared app as well as the tenant one.
When a user logs into a tenant they will only be able to use the users store in that tenant customauth not the shared one.
Below is what I think it should be
Let me know if it works
SHARED_APPS = (
'tenant_schemas', # mandatory
'customers', # you must list the app where your tenant model resides in
'django.contrib.contenttypes',
# everything below here is optional
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'customauth',
)
TENANT_APPS = (
# The following Django contrib apps must be in TENANT_APPS
'django.contrib.contenttypes',
'django.contrib.auth',
# your tenant-specific apps
'customauth',
)
Sadly it didn't seem to work:
TENANT_MODEL = "customers.Client"
AUTH_USER_MODEL = 'customauth.MyUser'
# Application definition
SHARED_APPS = (
'tenant_schemas', # mandatory
'customers', # you must list the app where your tenant model resides in
'django.contrib.contenttypes',
# everything below here is optional
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'customauth',
)
TENANT_APPS = (
# The following Django contrib apps must be in TENANT_APPS
'django.contrib.contenttypes',
'django.contrib.auth',
# your tenant-specific apps
'customauth',
)
INSTALLED_APPS = list(set(SHARED_APPS + TENANT_APPS))
it is giving me the same error:
$ python manage.py makemigrations customauth
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/core/management/commands/makemigrations.py", line 63, in handle
loader = MigrationLoader(None, ignore_no_migrations=True)
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/db/migrations/loader.py", line 47, in __init__
self.build_graph()
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/db/migrations/loader.py", line 287, in build_graph
parent = self.check_key(parent, key[0])
File "/home/odroid/Documents/django/thetest/env/lib/python3.4/site-packages/django/db/migrations/loader.py", line 165, in check_key
raise ValueError("Dependency on unknown app: %s" % key[0])
ValueError: Dependency on unknown app: customauth
(I can't be the first to try a custom user in django 1.8 with tenant schemas, but I am not sure what would be different). I can post a zip file (minus the env) if that would be helpful. Otherwise, other suggestions? I don't have a deep understanding of the migrations so am finding this hard to decipher.
I got it work however I used AbstractUser instead
class UserProfile(AbstractUser):
company_name = models.CharField(max_length=255, blank=True, null=True)
Would you mind posting the full custom user models.py and site settings.py files (for some reason I am still getting the unknown app issue, so I must have something different still)? And did you just do a python manage.py makemigrations or did you do a python manage.py makemigrations customuser and then python manage.py makemigrations?
If I get this going (err, when) I can maybe post a full example somewhere as it might be helpful for others.
I haven't had time to do this yet. I will try and do this soon however I am currently at Djangocon EU.
Just to put this to rest now. I finally figured out one issue and might have been my issue. I was clearing out the migrations directory (including the init.py file). Without the init.py file it was giving me the errors above. When I put the init.py file in there all the migrations ran correctly and database tables were created after the migrate_schemas --shared.
So, I have not fully tested that this will get me past my issues and not sure this will solve world problems but I wanted to note this just for some closure on this.
I had a similar issue and I discovered that I hadn't run the "makemigrations" for my custom user model before using "python manage.py migrate_schemas --shared".
also the same problem with custom user model.
This issue still exist. Who is solved this issue?
Hi, any updates on this issue? I am getting the same error which says a relation (part of tenant app) doesn't exist while performing "migrate_schemas --shared"
Hi, any updates on this issue? I am getting the same error which says a relation (part of tenant app) doesn't exist while performing "migrate_schemas --shared"
Hi spsree4U, did you manage to solve this issue ? If not, this is what worked for me
Settings
TENANT_MODEL = "customer.Client" AUTH_USER_MODEL = 'customauth.MyUser'
SHARED_APPS = ( 'tenant_schemas', 'customauth', 'customer', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', )
TENANT_APPS = ( 'customauth', 'django.contrib.contenttypes', )
INSTALLED_APPS = ( 'tenant_schemas', 'customauth', 'customer', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles' )
Migration
- python manage.py makemigrations customauth
- python manage.py makemigrations customer
- python manage.py migrate_schemas --shared
Environment python==3.7 Django==2.2 django-tenant-schemas==3.11.0
NB: Tested also with django==1.11 and django-tenant-schemas==1.9.0
Best of luck.