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

Address redundancy re default db setup #2729

Closed
phillxnet opened this issue Oct 31, 2023 · 22 comments
Closed

Address redundancy re default db setup #2729

phillxnet opened this issue Oct 31, 2023 · 22 comments

Comments

@phillxnet
Copy link
Member

As highlighed by @FroggyFlox & @Hooverdan96 as part of #2723, which concerns the smart_manager database and our services setup, we may similarly have a redundancy in how we establish, after dropping storageadmin, a new setup of the default databases "storageadmin".

As Rockstor pre-dates south's integration into Django we have some layers of legacy here. We also have. as part of our DB_SETUP in initrock (for new database instances only), a straight dump of all that has gone before via:

"psql storageadmin -w -f {}/storageadmin.sql.in".format(CONF_DIR)

However this dump contains many now redundant, and conflicting, migration details. For example, in this dump/restore file we have the following south migration detail as having been already applied within this sql dump:

6 oauth2_provider 0001_initial 2016-11-24 15:00:22.623774-08

And possibly then responsible for the indicated applied state for oauth2_provider's migrations. See the following comment for details:
#2727 (comment)

Which pertains to an older version of the initial db setup file of oauth2_provider (part of Django-oath-toolkit - an external app).
However as detailed in #2710 comment: #2710 (comment)
This initial setup/migration file for oauth2_provider has since been re-used as a squashed version now containing many of the follow-up model additions/alterations. Leading, in another part, to this issue's creation, to examine if our initial database setup, consisting of an initial (now old) db snapshot/dump file's restore, should be dropped in favour of using only migrations files to achieve the same. Especially give the dump contains models that are the responsibility of external applications. Inevitably leading to breakage/fragility when those projects modify/squash their migration files.

South migration files, and now Django's also, (over the life time of Rockstor) are 'tagged' as having been applied by their name only via a dedicated db table. This is thought to have now lead to our current inability to re-create a complete/sane oauth2_provider db setup, regarding new db setups only, our supposedly pre-applied (via dump file) migration now contains less than the post squash (into 0001_initial) migrations assume. And so some interim migrations are now missing from our external Django-oauth-toolkit library. But only on fresh db setups, as pre-existing databases prior to our ongoing work in #2727 used versions of this same library prior to this upstream squashing event.

@phillxnet
Copy link
Member Author

Newest Django-oath-toolkit 0001_initial migration contains, in part, the following model creation:

https://github.com/jazzband/django-oauth-toolkit/blob/4c1367942fcce5a8cb36d7e5fa4e39d481a361cc/oauth2_provider/migrations/0001_initial.py#L25C1-L44C11

        migrations.CreateModel(
            name='Application',
            fields=[
                ('id', models.BigAutoField(serialize=False, primary_key=True)),
                ('client_id', models.CharField(default=oauth2_provider.generators.generate_client_id, unique=True, max_length=100, db_index=True)),
                ('redirect_uris', models.TextField(help_text='Allowed URIs list, space separated', blank=True)),
                ('client_type', models.CharField(max_length=32, choices=[('confidential', 'Confidential'), ('public', 'Public')])),
                ('authorization_grant_type', models.CharField(max_length=32, choices=[('authorization-code', 'Authorization code'), ('implicit', 'Implicit'), ('password', 'Resource owner password-based'), ('client-credentials', 'Client credentials')])),
                ('client_secret', models.CharField(default=oauth2_provider.generators.generate_client_secret, max_length=255, db_index=True, blank=True)),
                ('name', models.CharField(max_length=255, blank=True)),
                ('user', models.ForeignKey(related_name="oauth2_provider_application", blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)),
                ('skip_authorization', models.BooleanField(default=False)),
                ('created', models.DateTimeField(auto_now_add=True)),
                ('updated', models.DateTimeField(auto_now=True)),
            ],
            options={
                'abstract': False,
                'swappable': 'OAUTH2_PROVIDER_APPLICATION_MODEL',
            },
        ),

Where as we have the same model creation in our storageadmin.sql.in of:

CREATE TABLE oauth2_provider_application (
    id integer NOT NULL,
    client_id character varying(100) NOT NULL,
    user_id integer NOT NULL,
    redirect_uris text NOT NULL,
    client_type character varying(32) NOT NULL,
    authorization_grant_type character varying(32) NOT NULL,
    client_secret character varying(255) NOT NULL,
    name character varying(255) NOT NULL,
    skip_authorization boolean NOT NULL
);
...

With a number of follow-ups which if all interim migrations are also then applied, should result in the same state.

Note also that the failure we see in: #2727 (comment)
When attempting to apply new Djanog-oath-toolkit migration:

oauth2_provider.0006_alter_application_client_secret

'psycopg2.errors.UndefinedColumn: column oauth2_provider_application.created does not exist'

was part of our proposed 'skipped' migrations (on new db instantiation) via the upstream squash commit:

jazzband/django-oauth-toolkit@32bba99

Where "oauth2_provider/migrations/0005_auto_20170514_1141.py" contained our example failure re application.created:

        migrations.AddField(
            model_name='application',
            name='created',
            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
            preserve_default=False,
        ),

@phillxnet
Copy link
Member Author

A pg_dump extract from our current migration of oauth2_provider via:

/usr/bin/pg_dump --dbname=storageadmin --schema='public' --table=public."oauth2_provider_application" --file="/root/{data_source}-{timestamp}-dump.sql" --clean

created by PyCharm, contained in part:

--
-- Name: oauth2_provider_application; Type: TABLE; Schema: public; Owner: rocky
--

CREATE TABLE public.oauth2_provider_application (
    id bigint DEFAULT nextval('public.oauth2_provider_application_id_seq'::regclass) NOT NULL,
    client_id character varying(100) NOT NULL,
    user_id integer,
    redirect_uris text NOT NULL,
    client_type character varying(32) NOT NULL,
    authorization_grant_type character varying(32) NOT NULL,
    client_secret character varying(255) NOT NULL,
    name character varying(255) NOT NULL,
    skip_authorization boolean NOT NULL,
    created timestamp with time zone NOT NULL,
    updated timestamp with time zone NOT NULL,
    algorithm character varying(5) NOT NULL,
    post_logout_redirect_uris text NOT NULL
);

With the extra fields likely down to further migrations from the above squashed 0001 migration file.

@phillxnet
Copy link
Member Author

phillxnet commented Oct 31, 2023

A likely component here is to have non --fake-initial migrations applied, when no .initrock file exists, instead of our current sql dump use. But I'm a little concerned we don't have representative/complete 0001_initial migrations across the board.

My next investigation area.

It might also be nice to re-enable our admin capabilities: but his may be a step too far here, especially given the potential difficulties in migrating the last stable release similarly - which would be a priority here.

@phillxnet
Copy link
Member Author

From the contents of our 0001_initial migration for the default database (storageadmin) we see no:

  • auth*
  • django*
    Entries (i.e model creations). Suggesting that our current 0001_initial was created against a database pre-populated from the above dump. This complicates things somewhat. It may be we have to piece-meal migrate all entries in our early storageadmin dump to be similarly executed by the 0001_initial, given existing installs (with .initrock in place) skip this 0001_initial file anyway does give us some leeway, assuming we maintain compatibility with all subsequent migration files.

Squashing at this point (5.0.5-0), to combine all current migrations into 0001_initial would break stable to stable updates, not ideal. We could modify our target version in this issue to that of our last stable, but again this breaks the current testing phase installs. And we only have 18 migration files for storageadmin currently.

Another interim step under consideration here is to simply remove all oauth2_provider entries from our initial dump, removing them from interfering (with new db setups) with our newly instated (from upstream updates) Django-oath-toolkit.

@phillxnet
Copy link
Member Author

phillxnet commented Nov 1, 2023

Notes

# Wipe our databases; our "drop_and_recreate" step.
su - postgres -c "psql -w -f /opt/rockstor/conf/postgresql_setup.sql"
# Apply only contents of storageadmin.sql.in our existing "populate_storageadmin" step.
su - postgres -c "psql storageadmin -w -f /opt/rockstor/conf//storageadmin.sql.in"

The result contains the following tables:

  1. auth_*
  2. django_*
  3. oauth2_provider*
  4. south_migrationshistory (populated with our prior 52 south migrations)
  5. storageadmin_*

N.B. there is no django_migrations table.

Pertaining to #2727

id app_name migration applied
6 oauth2_provider 0001_initial 2016-11-24 23:00:22.623774 +00:00
49 oauth2_provider 0002_adding_indexes 2016-11-24 23:00:32.042776 +00:00
50 oauth2_provider 0003_auto__add_field_application_skip_authorization__chg_field_accesstoken_ 2016-11-24 23:00:32.151440 +00:00

These migrations look to date back to when django-oauth-toolkit itself migrated to south:
jazzband/django-oauth-toolkit@5fe4029#diff-b26f9ceb70ef54c0f525ff3853470a9ecce04fd8ac75cff9ce7d71a4209fc5e4

@phillxnet
Copy link
Member Author

Our current "migrations" directories, including external apps:

lbuildvm:/opt/rockstor # find . -type d -name "migrations"
./src/rockstor/smart_manager/migrations
./src/rockstor/storageadmin/migrations
./.venv/lib/python3.9/site-packages/django/conf/app_template/migrations
./.venv/lib/python3.9/site-packages/django/contrib/admin/migrations
./.venv/lib/python3.9/site-packages/django/contrib/auth/migrations
./.venv/lib/python3.9/site-packages/django/contrib/contenttypes/migrations
./.venv/lib/python3.9/site-packages/django/contrib/flatpages/migrations
./.venv/lib/python3.9/site-packages/django/contrib/redirects/migrations
./.venv/lib/python3.9/site-packages/django/contrib/sessions/migrations
./.venv/lib/python3.9/site-packages/django/contrib/sites/migrations
./.venv/lib/python3.9/site-packages/django/db/migrations
./.venv/lib/python3.9/site-packages/rest_framework/authtoken/migrations
./.venv/lib/python3.9/site-packages/oauth2_provider/migrations

Our storageadmin.sql.in, for our default db setup, contains copies of older migrations for:

Package App / Apps
Django (admin, auth, contenttypes, sessions, sites)
Django oath toolkit oauth2_provider
Rockstor storageadmin

@Hooverdan96
Copy link
Member

you guys opened pandora's database migration box with that innocent question of whether the database dump is still needed, it seems ...

@phillxnet
Copy link
Member Author

@Hooverdan96 Yes, but it would be good to have this more simplified, or at least managed by a single system: now it exists. Plus we do have a blocker here re the Django-oath-toolkit update pr linked. So we have to see to at least that for the time being. But getting there - just a little more experimentation and I hope to have a clearer picture of our options.

@phillxnet
Copy link
Member Author

phillxnet commented Nov 2, 2023

In above comment: #2729 (comment)
we have an oauth2_provider migration of unknown origin, likely pre-applied within our db dump file.

  • 0003_auto__add_field_application_skip_authorization__chg_field_accesstoken_

Not noting in case this comes back to haunt us. I've had a look upstream and haven't seen this particular migration.

@phillxnet
Copy link
Member Author

phillxnet commented Nov 2, 2023

The origin of our current database dump dates back to:
a148124
Which looks to be part of a long past Django update !!
#1190
Where we moved away form South to the then new South intergration within Django (native Django migrations).

And the following appears to be the point where our storageadmin 0001_initial was transition to native migrations.
schakrava@db31574#diff-5be0b76e17601154cb67ecffb7d1edb893cd7d2d6d82d404f465e54997b82c1a

See PR: #1546

Note in: a148124#diff-ef94f8c57536aaab159776f4c01cf8f73d25130dbb7f61b6f9ad14dab6da6e82
We see the last update of our dump storageadmin.sql.in pg_dump.

@phillxnet
Copy link
Member Author

# Wipe our databases; our "drop_and_recreate" step.
su - postgres -c "psql -w -f /opt/rockstor/conf/postgresql_setup.sql"
# atemp to re-instate our initial db from migrations only
export DJANGO_SETTINGS_MODULE=settings
cd /opt/rockstor/
lbuildvm:/opt/rockstor # poetry run django-admin showmigrations
admin
 [ ] 0001_initial
 [ ] 0002_logentry_remove_auto_add
 [ ] 0003_logentry_add_action_flag_choices
auth
 [ ] 0001_initial
 [ ] 0002_alter_permission_name_max_length
 [ ] 0003_alter_user_email_max_length
 [ ] 0004_alter_user_username_opts
 [ ] 0005_alter_user_last_login_null
 [ ] 0006_require_contenttypes_0002
 [ ] 0007_alter_validators_add_error_messages
 [ ] 0008_alter_user_username_max_length
 [ ] 0009_alter_user_last_name_max_length
 [ ] 0010_alter_group_name_max_length
 [ ] 0011_update_proxy_permissions
contenttypes
 [ ] 0001_initial
 [ ] 0002_remove_content_type_name
oauth2_provider
 [ ] 0001_initial
 [ ] 0002_08_updates
 [ ] 0003_auto_20160316_1503
 [ ] 0004_auto_20160525_1623
 [ ] 0005_auto_20170514_1141
 [ ] 0006_auto_20171214_2232
sessions
 [ ] 0001_initial
sites
 [ ] 0001_initial
 [ ] 0002_alter_domain_unique
smart_manager
 [ ] 0001_initial
 [ ] 0002_auto_20170216_1212
 [ ] 0003_auto_20230810_1143
storageadmin
 [ ] 0001_initial
 [ ] 0002_auto_20161125_0051
 [ ] 0003_auto_20170114_1332
 [ ] 0004_auto_20170523_1140
 [ ] 0005_auto_20180913_0923
 [ ] 0006_dcontainerargs
 [ ] 0007_auto_20181210_0740
 [ ] 0008_auto_20190115_1637
 [ ] 0009_auto_20200210_1948
 [ ] 0010_sambashare_time_machine
 [ ] 0011_auto_20200314_1207
 [ ] 0012_auto_20200429_1428
 [ ] 0013_auto_20200815_2004
 [ ] 0014_rockon_taskid
 [ ] 0015_auto_20220918_1524
 [ ] 0016_auto_20221020_1605
 [ ] 0017_auto_20230810_1141
 [ ] 0018_auto_20231009_1827

# oath2_providers migrations: `.venv/lib/python3.9/site-packages/oauth2_provider/migrations`

# Using the dependencies own ordering/inter-dependency definitions,
#  we have the following ordering:
lbuildvm:/opt/rockstor # poetry run django-admin migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, oauth2_provider, sessions, sites, smart_manager, storageadmin
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying oauth2_provider.0001_initial... OK
  Applying oauth2_provider.0002_08_updates... OK
  Applying oauth2_provider.0003_auto_20160316_1503... OK
  Applying oauth2_provider.0004_auto_20160525_1623... OK
  Applying oauth2_provider.0005_auto_20170514_1141... OK
  Applying oauth2_provider.0006_auto_20171214_2232... OK
  Applying sessions.0001_initial... OK
  Applying sites.0001_initial... OK
  Applying sites.0002_alter_domain_unique... OK
  Applying smart_manager.0001_initial... OK
  Applying smart_manager.0002_auto_20170216_1212... OK
  Applying smart_manager.0003_auto_20230810_1143... OK
  Applying storageadmin.0001_initial... OK
  Applying storageadmin.0002_auto_20161125_0051... OK
  Applying storageadmin.0003_auto_20170114_1332... OK
  Applying storageadmin.0004_auto_20170523_1140... OK
  Applying storageadmin.0005_auto_20180913_0923... OK
  Applying storageadmin.0006_dcontainerargs... OK
  Applying storageadmin.0007_auto_20181210_0740... OK
  Applying storageadmin.0008_auto_20190115_1637... OK
  Applying storageadmin.0009_auto_20200210_1948... OK
  Applying storageadmin.0010_sambashare_time_machine... OK
  Applying storageadmin.0011_auto_20200314_1207... OK
  Applying storageadmin.0012_auto_20200429_1428... OK
  Applying storageadmin.0013_auto_20200815_2004... OK
  Applying storageadmin.0014_rockon_taskid... OK
  Applying storageadmin.0015_auto_20220918_1524... OK
  Applying storageadmin.0016_auto_20221020_1605... OK
  Applying storageadmin.0017_auto_20230810_1141... OK
  Applying storageadmin.0018_auto_20231009_1827... OK

With the resulting Django native migration record now established as:

lbuildvm:/opt/rockstor # poetry run django-admin showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
oauth2_provider
 [X] 0001_initial
 [X] 0002_08_updates
 [X] 0003_auto_20160316_1503
 [X] 0004_auto_20160525_1623
 [X] 0005_auto_20170514_1141
 [X] 0006_auto_20171214_2232
sessions
 [X] 0001_initial
sites
 [X] 0001_initial
 [X] 0002_alter_domain_unique
smart_manager
 [X] 0001_initial
 [X] 0002_auto_20170216_1212
 [X] 0003_auto_20230810_1143
storageadmin
 [X] 0001_initial
 [X] 0002_auto_20161125_0051
 [X] 0003_auto_20170114_1332
 [X] 0004_auto_20170523_1140
 [X] 0005_auto_20180913_0923
 [X] 0006_dcontainerargs
 [X] 0007_auto_20181210_0740
 [X] 0008_auto_20190115_1637
 [X] 0009_auto_20200210_1948
 [X] 0010_sambashare_time_machine
 [X] 0011_auto_20200314_1207
 [X] 0012_auto_20200429_1428
 [X] 0013_auto_20200815_2004
 [X] 0014_rockon_taskid
 [X] 0015_auto_20220918_1524
 [X] 0016_auto_20221020_1605
 [X] 0017_auto_20230810_1141
 [X] 0018_auto_20231009_1827

@FroggyFlox & @Hooverdan96 this looks promising for a move to dump all sql.in file initialisation. But as @FroggyFlox has noted in the past, we then have our smart_manager entries applied to the 'default' db of storageadmin, where-as they normally live in the smartdb database. Likely indicating we have an issue with our database router !!

@phillxnet
Copy link
Member Author

Our existing router is defined in settings.py as:

DATABASE_ROUTERS = [
    "smart_manager.db_router.SmartManagerDBRouter",
]

@phillxnet
Copy link
Member Author

phillxnet commented Nov 2, 2023

From: https://docs.djangoproject.com/en/4.2/topics/db/multi-db/#topics-db-multi-db-routing

Databases can have any alias you choose. However, the alias default has special significance. Django uses the database with the alias of default when no other database has been selected.

Our db alias use, from DATABASES in settings.py are

  • "default" for the "storageadmin" name within postgres
  • smart_manager" for the "smartdb" name within postgres

From: https://docs.djangoproject.com/en/4.2/topics/db/multi-db/#synchronizing-your-databases

Synchronizing your databases:
The migrate management command operates on one database at a time. By default, it operates on the default database, but by providing the --database option, you can tell it to synchronize a different database.

Which is mostly what we have done to date, but now exploring routers to try and explore automating the passage of appropriate models to smart_manager, in an attempt to keep our migrations as simple as possible.

If you don’t want every application to be synchronized onto a particular database, you can define a database router that implements a policy constraining the availability of particular models.

@Hooverdan96
Copy link
Member

Hooverdan96 commented Nov 2, 2023

Could that be as simple as replicating the db_router.py for the storageadmin db (withe APP_LABEL = storageadmin?
or might also require a change to the allow_migrate method(when looking at this post: https://stackoverflow.com/questions/67514890/django-database-routing)

@phillxnet
Copy link
Member Author

phillxnet commented Nov 2, 2023

@Hooverdan96 Not entirely sure, have seen that post also. Still fathoming as it goes. Pretty sure if our existing router returns None there is a fail/fall through to the default router though. So keen to keep as simple as possible. We may have a False where there should be a None thought.

[EDIT] https://dboostme.medium.com/using-django-with-multiple-databases-introduction-8f0ffb409995
Seems to suggest the None from all routers specified results in default router picking up the fall-throughts.

@phillxnet
Copy link
Member Author

I think we are just missing a 'model_name' sensitivity in our existing router.

@phillxnet
Copy link
Member Author

phillxnet commented Nov 3, 2023

While experimenting with router configuration, it seems that if we request smart_manager model to go to smart_manager and do a generic migration we still end up with django_migrate table (within 'default'/smartmanager) showing these migrations as having been applied. This is due, I assume, the them having been considered by that database. Their associated actions are not, however, enacted upon. Strange for me, but I think it's down to Django having the ability to have the same migrations applied to multiple databases: but we want smart_manager models to only be instantiated in smart_manager. That was quite the confusion. More details to follow.

I.e. we have clear upstream docs stating that django-admin migrate only works on a single database, and if no database= option is given it defaults to the default db, which for us is storageadmin (in postgres).

https://docs.djangoproject.com/en/4.2/ref/django-admin/#migrate

No arguments: All apps have all of their migrations run.

So maybe we read this as the migrations for app smart_manager on the 'default' db have been run/considered:

...
Applying smart_manager.0001_initial... OK
Applying smart_manager.0002_auto_20170216_1212... OK
Applying smart_manager.0003_auto_20230810_1143... OK
...

But the router has deemed no action: I can't seem to get those migrations to go to the smart_manager db as the default command (without database specified) does not deal with anything other than the 'default' database. And these migrations are, by virtue of the in-development router changes, not targeted for this db - but are considered !!

Still verifying the above with the router changes in-development.
I.e.:

poetry run django-admin showmigrations --database=default

show all migrations as applied, confirmed in django_migrations table created in storageadmin, after django-admin migrate

But: poetry run django-admin showmigrations --database=smart_manager
show nothing as having been applied, as we have yet to address this database: given (I think) migrations via django-admin migrate only work on one database at a time.

@phillxnet
Copy link
Member Author

poetry run django-admin migrate --database=smart_manager

Also indicates having processed all migrations for all models and apps!!

OK, so poetry run django-admin showmigrations --database=smart_manager also indicates that all migrations have been applied (to smart_manager) after poetry run django-admin migrate --database=smart_manager not quite what we want. I'll dabble further.

But on the plus side smart_manager contains the smart_manager models, but storageadmin (default) does not. Likely the in-dev model is filtering out smart_manager models for default, but not filtering out all other models intended only for default. Nearly there I think. Trying to get the router to do as much as possible for us.

@phillxnet
Copy link
Member Author

poetry run django-admin migrate --database=smart_manager

Migrates all smart_manager models (22) into postgres smartdb but showmigrations (for smart_manager), & records in django_migrations (in smartdb), all as having been processed !! None entires or completed migrations show up for default.

poetry run django-admin migrate (defaulting to 'default' db which is our storageadmin)

Migrates all Django apps (auth, django, oath2_provider) and our storageadmin models (72 in total for this db), but again showmigrations (for 'default'), & django_migrations table within storageadmin (postgresql) records all migrations as having been applied.

So as-is the new router looks to do the right thing, but the end result, in each db, is that all migrations look to have been applied (irrispective of if they belong to the database being queried). So it looks like showmigrations actually shows what migrations have been processed for the target database: but only those relevant to the database in question are actually being created/applied.

I think my confusion is with us previously specifying individual apps, and likely with our prior router not functioning to block smart_manager destined models from being created in 'default'. Not sure if non smart_manager models would end up in smart_manager as they did earlier here for me (but no longer) however.

@phillxnet
Copy link
Member Author

phillxnet commented Nov 4, 2023

Proposed new router (linked draft-pr)

Wipe both our dbs (with no current connections) via:
su - postgres -c "psql -w -f /opt/rockstor/conf/postgresql_setup.sql"

poetry run django-admin showmigrations show all migrations not applied (for default db)

poetry run django-admin migrate

Looks to apply all known models/migrations with:
poetry run django-admin showmigrations
confirming all have been 'processed', (including smart_manager intended ones). However all exept smart_manager models/migrations have been created in 'default' db (storageadmin)

Similarly:
poetry run django-admin showmigrations --database=smart_manager
show all migrations not applied (for smartdb/smart_manager db)

poetry run django-admin migrate --database=smart_manager

Looks to apply all known models/migrations via:
poetry run django-admin showmigrations --database=smart_manager

However as above with the default the db, smart_manager now contains only our intended 22 smart_manager models/migrations along with the django_migrations table (containg all migrations across all apps !! As having been 'processed').

So given we specified no app for either database and all models ended up where they were intended this looks to be a good start re the proposed db router.

phillxnet added a commit to phillxnet/rockstor-core that referenced this issue Nov 4, 2023
We currently use both an initial (years old) pg_dump, &
Djangoes native migration system to setup our initial
database structure. This patch proposes that we drop the
initial setup via sql.in files and normalise on using only
the Django migration files. The fix purpose here is to
accommodate upstream squash events such as one observed
in Django-oath-toolkit, which introduced a migration
conflict with our existing initial/static db setup via
the old storageadmin.sql.in dump file.

# Includes
- Revised database router to ensure the existing model/db
separation regarding the smart_manager app and its use of
only the dedicated smart_manager database. Along with
migration awareness, so that model metadata 'app_label'
informs each migration appropriately: wise to the currently
specified detabase during `django-admin migrate` runs.
@phillxnet
Copy link
Member Author

We still have the option, for say smart_manager only, to process only the relevant migrations for that db/app via:

poetry run django-admin migrate --database=smart_manager smart_manager
Operations to perform:
  Apply all migrations: smart_manager
Running migrations:
  Applying smart_manager.0001_initial... OK
  Applying smart_manager.0002_auto_20170216_1212... OK
  Applying smart_manager.0003_auto_20230810_1143... OK

Which is much quicker and leaves us with only a record of the relevant 'processed' migrations in that database:

 poetry run django-admin showmigrations --database=smart_manager
...
sites
 [ ] 0001_initial
 [ ] 0002_alter_domain_unique
smart_manager
 [X] 0001_initial
 [X] 0002_auto_20170216_1212
 [X] 0003_auto_20230810_1143
storageadmin
 [ ] 0001_initial
 [ ] 0002_auto_20161125_0051
...

This is the proposed approach for the new db setup mechanism (in initrock.py) that I'm working on, for both databases now. This leaves us with the generic default initial setup/migration command of;:

poetry run django-admin migrate

Which can then, auto-sort application order etc.

phillxnet added a commit to phillxnet/rockstor-core that referenced this issue Nov 4, 2023
- Remove old/legacy and now redundant smartdb.sql.in &
storageadmin.sql.in files, and south_migrations archive
directories for both databases.
- Move db setup/migration code in initrock script to fstrings.
- DB migration mechanisms not associated with the initial DB
setup are not functionally modified, as this is outside the
scope intended for this patch.
phillxnet added a commit to phillxnet/rockstor-core that referenced this issue Nov 6, 2023
We currently use both an initial (years old) pg_dump, &
Djangoes native migration system to setup our initial
database structure. This patch proposes that we drop the
initial setup via sql.in files and normalise on using only
the Django migration files. The fix purpose here is to
accommodate upstream squash events such as one observed
in Django-oath-toolkit, which introduced a migration
conflict with our existing initial/static db setup via
the old storageadmin.sql.in dump file.

# Includes
- Revised database router to ensure the existing model/db
separation regarding the smart_manager app and its use of
only the dedicated smart_manager database. Along with
migration awareness, so that model metadata 'app_label'
informs each migration appropriately: wise to the currently
specified detabase during `django-admin migrate` runs.
- Remove old/legacy and now redundant smartdb.sql.in &
storageadmin.sql.in files, and south_migrations archive
directories for both databases.
- Move db setup/migration code in initrock script to fstrings.
- DB migration mechanisms not associated with the initial DB
setup are not functionally modified, as this is outside the
scope intended for this patch.
@phillxnet phillxnet changed the title Address suspected redundancy re default db setup Address redundancy re default db setup Nov 6, 2023
phillxnet added a commit that referenced this issue Nov 7, 2023
…atabase-setup

Address redundancy re database setup #2729
@phillxnet
Copy link
Member Author

Closing as:
Fixed by #2733

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