Closed killer24vrccp closed 4 months ago
What do your models and migrations look like? Guessing you have a dependency between them.
Look respective screen shot. I have company and account apps.
That's a little helpful, but I don't see anything being related to one another. Can you share the full contents of the migrations? Also, maybe your SHARED_APPS
and TENANT_APPS
settings.
I'm wondering if each migration has dependencies
set to one another.
Yes of course!
My settings is:
Migration about Account app
# Generated by Django 4.2.13 on 2024-05-11 06:00
from django.db import migrations, models
import tenant_users.permissions.models
class Migration(migrations.Migration):
initial = True
dependencies = [
('company', '__first__'),
]
operations = [
migrations.CreateModel(
name='TenantUser',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('email', models.EmailField(db_index=True, max_length=254, unique=True, verbose_name='Email Address')),
('is_active', models.BooleanField(default=True, verbose_name='active')),
('is_verified', models.BooleanField(default=False, verbose_name='verified')),
('name', models.CharField(blank=True, max_length=64)),
('tenants', models.ManyToManyField(blank=True, help_text='The tenants this user belongs to.', related_name='user_set', to='company.company', verbose_name='tenants')),
],
options={
'abstract': False,
},
bases=(models.Model, tenant_users.permissions.models.PermissionsMixinFacade),
),
]
My migration about Company app
# Generated by Django 4.2.13 on 2024-05-11 06:00
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django_tenants.postgresql_backend.base
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Company',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('schema_name', models.CharField(db_index=True, max_length=63, unique=True, validators=[django_tenants.postgresql_backend.base._check_schema_name])),
('slug', models.SlugField(blank=True, verbose_name='Tenant URL Name')),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=255, verbose_name='Name')),
('description', models.CharField(blank=True, null=True, verbose_name='Description')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Domain',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain', models.CharField(db_index=True, max_length=253, unique=True)),
('is_primary', models.BooleanField(db_index=True, default=True)),
('tenant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='domains', to='company.company')),
],
options={
'abstract': False,
},
),
]
Your Company migration depends on the User model, and the User migration depends on the Company. I would delete your migrations and create the Company
app first, and then the Account
app.
I try and I have same result.
Migration removed.
Result with my terminal:
(.venv) PS D:\Projet\TTLtenant> python .\manage.py makemigrations company
Migrations for 'company':
app\generic\company\migrations\0001_initial.py
- Create model Company
- Create model Domain
(.venv) PS D:\Projet\TTLtenant> python .\manage.py makemigrations account
Migrations for 'account':
app\generic\account\migrations\0001_initial.py
- Create model TenantUser
(.venv) PS D:\Projet\TTLtenant> python .\manage.py migrate_schemas --shared
[standard:public] === Starting migration
Traceback (most recent call last):
File ".\manage.py", line 22, in <module>
main()
File ".\manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\core\management\__init__.py", line 442, in execute_from_command_line
utility.execute()
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\core\management\__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\core\management\base.py", line 412, in run_from_argv
self.execute(*args, **cmd_options)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\core\management\base.py", line 458, in execute
output = self.handle(*args, **options)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django_tenants\management\commands\migrate_schemas.py", line 63, in handle
executor.run_migrations(tenants=[self.PUBLIC_SCHEMA_NAME])
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django_tenants\migration_executors\standard.py", line 11, in run_migrations
run_migrations(self.args, self.options, self.codename, self.PUBLIC_SCHEMA_NAME)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django_tenants\migration_executors\base.py", line 59, in run_migrations
migrate_command_class(stdout=stdout, stderr=stderr).execute(*args, **options)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\core\management\base.py", line 458, in execute
output = self.handle(*args, **options)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\core\management\base.py", line 106, in wrapper
res = handle_func(*args, **kwargs)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\core\management\commands\migrate.py", line 117, in handle
executor = MigrationExecutor(connection, self.migration_progress_callback)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\db\migrations\executor.py", line 18, in __init__
self.loader = MigrationLoader(self.connection)
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\db\migrations\loader.py", line 58, in __init__
self.build_graph()
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\db\migrations\loader.py", line 305, in build_graph
self.graph.ensure_not_cyclic()
File "D:\Projet\TTLtenant\.venv\lib\site-packages\django\db\migrations\graph.py", line 284, in ensure_not_cyclic
raise CircularDependencyError(
django.db.migrations.exceptions.CircularDependencyError: account.0001_initial, company.0001_initial
Thanks you for your helpfull!
Interesting ... what do the migrations contain? Try to include details to help troubleshoot.
This is migrations for account:
# Generated by Django 4.2.13 on 2024-05-16 04:17
from django.db import migrations, models
import tenant_users.permissions.models
class Migration(migrations.Migration):
initial = True
dependencies = [
('company', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='TenantUser',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('email', models.EmailField(db_index=True, max_length=254, unique=True, verbose_name='Email Address')),
('is_active', models.BooleanField(default=True, verbose_name='active')),
('is_verified', models.BooleanField(default=False, verbose_name='verified')),
('name', models.CharField(blank=True, max_length=64)),
('tenants', models.ManyToManyField(blank=True, help_text='The tenants this user belongs to.', related_name='user_set', to='company.company', verbose_name='tenants')),
],
options={
'abstract': False,
},
bases=(models.Model, tenant_users.permissions.models.PermissionsMixinFacade),
),
]
Migration for company:
# Generated by Django 4.2.13 on 2024-05-16 04:17
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django_tenants.postgresql_backend.base
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Company',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('schema_name', models.CharField(db_index=True, max_length=63, unique=True, validators=[django_tenants.postgresql_backend.base._check_schema_name])),
('slug', models.SlugField(blank=True, verbose_name='Tenant URL Name')),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=255, verbose_name='Name')),
('description', models.CharField(blank=True, null=True, verbose_name='Description')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Domain',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain', models.CharField(db_index=True, max_length=253, unique=True)),
('is_primary', models.BooleanField(db_index=True, default=True)),
('tenant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='domains', to='company.company')),
],
options={
'abstract': False,
},
),
]
I don't know if can help but I add some additional settings
And my MiddlerWares:
My project structure:
If I start with the example that's work but when I copy exactly the samethings that's don't work. It's very weird. I don't understand why and I give that at ChatGPT or Gemini and nothing that's work for resolve it.
Looks like it created the same migration dependencies. Are you sure there's no dependency between any of the Company models and the UserModel or anything from Account app?
It's a new project and I have setup only django-tenants and django-tenant-users. All models include there models is on screenshot 😪
I would go step by step. Delete the migrations, create the migrations for Account. See what it contains. Then do Company, see what that contains. Is there a circular dependency or not? Does that work?
look at the test app here and you’ll see the migration dependencies on the initial migrations.
I have rerun migration and I compare difference:
My model:
Example model:
from django.db import migrations, models
from tenant_users.permissions.models import PermissionsMixinFacade
class Migration(migrations.Migration):
"""Initial migration for test_django_tenants.users app."""
initial = True
dependencies = [
("companies", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="TenantUser",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"password",
models.CharField(
max_length=128,
verbose_name="password",
),
),
(
"last_login",
models.DateTimeField(
blank=True,
null=True,
verbose_name="last login",
),
),
(
"email",
models.EmailField(
db_index=True,
max_length=254,
unique=True,
verbose_name="Email Address",
),
),
(
"is_active",
models.BooleanField(
default=True,
verbose_name="active",
),
),
(
"is_verified",
models.BooleanField(default=False, verbose_name="verified"),
),
("name", models.CharField(blank=True, max_length=64)),
(
"tenants",
models.ManyToManyField(
blank=True,
help_text="The tenants this user belongs to.",
related_name="user_set",
to="companies.Company",
verbose_name="tenants",
),
),
],
options={
"abstract": False,
},
bases=(
models.Model,
PermissionsMixinFacade,
),
),
]
In my company:
# Generated by Django 4.2.13 on 2024-05-16 05:05
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django_tenants.postgresql_backend.base
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Company',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('schema_name', models.CharField(db_index=True, max_length=63, unique=True, validators=[django_tenants.postgresql_backend.base._check_schema_name])),
('slug', models.SlugField(blank=True, verbose_name='Tenant URL Name')),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('name', models.CharField(max_length=255, verbose_name='Name')),
('description', models.CharField(blank=True, null=True, verbose_name='Description')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Domain',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('domain', models.CharField(db_index=True, max_length=253, unique=True)),
('is_primary', models.BooleanField(db_index=True, default=True)),
('tenant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='domains', to='company.company')),
],
options={
'abstract': False,
},
),
]
In example migration:
from django.db import migrations, models
from django_tenants.postgresql_backend.base import (
_check_schema_name as check_schema_name,
)
class Migration(migrations.Migration):
"""Initial migration for test_django_tenants.companies app."""
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="Company",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"schema_name",
models.CharField(
db_index=True,
max_length=63,
unique=True,
validators=[check_schema_name],
),
),
(
"slug",
models.SlugField(
blank=True,
verbose_name="Tenant URL Name",
),
),
("created", models.DateTimeField()),
("modified", models.DateTimeField(blank=True)),
("name", models.CharField(max_length=64)),
("description", models.TextField()),
],
options={
"abstract": False,
},
),
migrations.CreateModel(
name="Domain",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"domain",
models.CharField(
db_index=True,
max_length=253,
unique=True,
),
),
(
"is_primary",
models.BooleanField(
db_index=True,
default=True,
),
),
(
"tenant",
models.ForeignKey(
on_delete=models.deletion.CASCADE,
related_name="domains",
to="companies.company",
),
),
],
options={
"abstract": False,
},
),
]
It's better if I start with example project ?
I have fixed issue. I have copied django-tenant-users test on this Github and I stole existing migration. I think migration is write manually.
Provide a general summary of the issue in the title above.
Expected Behavior
Just migrate data with
python manage.py migrate_schemas --shared
.Actual Behavior
I get
django.db.migrations.exceptions.CircularDependencyError: company.0001_initial, account.0001_initial
Possible Fix
Not obligatory, but you can suggest a fix or reason for the bug.