How to delete app learning completely?

I have installed: Learning - Apps - App Store - Nextcloud

Now i want to uninstall it. After doing that all the tables and db stuff is remaining. Which kind of things i need to delte from the db that its completely removed. It should also work to install it again later if needed.

Currently I deleted from oc_migration, oc_appconfig and tables with “learning” in within the name.
anything else?

Why do you wish to purge it from the database? Cost of the added MB’s of storage?

I know how to use SQL. It would be just nice if there is a list of tables and data which i can purge from the db, so that no inconsistency is left.

Is there?

It is up to the individual app developer. Apps generally create their own app specific tables. Some include uninstall / deletion / clearing commands.

I don’t see one in that app’s repo. However you can manually review the app’s DB migrations:

There is a newer method of viewing the schema, but an app has to be support it and many do not yet.

If you interessted as well, this is what will happen with my request:

Thanks — valid point, and no, there is currently no automatic cleanup. Here is both the why and the full manual list.

Why there is no auto-cleanup today

Nextcloud never drops migration-created tables on its own. The core Installer::removeApp() docblock states it plainly:

The function will not delete preferences, tables and the configuration, this has to be done by the function oc_app_uninstall().

The only hook an app gets is <repair-steps><uninstall> in info.xml. The catch: that step is executed from AppManager::disableApp() — the very same code path that runs when an admin merely clicks Disable in the Apps UI. The step cannot tell “disable” from “remove”. Putting DROP TABLE there means one accidental disable wipes every course, question pool and certificate on the instance. That is why virtually no Nextcloud app auto-drops its schema, and why we did not either.

The right shape is an explicit, opt-in occ learning:uninstall command. It is on the list now (see below).

Manual cleanup list

Verified against a live NC 33 / PostgreSQL 16 instance running Learning 5.2.1. Table names are shown with the default oc_ prefix — substitute your own dbtableprefix from config.php.

1. Drop the 54 app tables

oc_learning_ai_chat_memory              oc_learning_gameshow_answers
oc_learning_analytics                   oc_learning_gameshow_players
oc_learning_ans_translations            oc_learning_gameshow_sessions
oc_learning_answers                     oc_learning_kudos
oc_learning_assignments                 oc_learning_league_challenges
oc_learning_audit_chain_state           oc_learning_league_results
oc_learning_audit_checkpoints           oc_learning_league_seasons
oc_learning_audit_events                oc_learning_leitner_items
oc_learning_campaign_state              oc_learning_mission_claims
oc_learning_certificates                oc_learning_oversight
oc_learning_cert_keys                   oc_learning_pools
oc_learning_coop_players                oc_learning_pool_shares
oc_learning_coop_sessions               oc_learning_qst_translations
oc_learning_coop_votes                  oc_learning_questions
oc_learning_course_announcements        oc_learning_rag_chunks
oc_learning_course_curriculum_scopes    oc_learning_recert_reminders
oc_learning_course_documents            oc_learning_sessions
oc_learning_course_exam_slots           oc_learning_story_progress
oc_learning_course_members              oc_learning_support_tickets
oc_learning_course_pools                oc_learning_user_answers
oc_learning_course_question_overrides   oc_learning_user_badges
oc_learning_courses                     oc_learning_user_stats
oc_learning_course_schedule             oc_learning_user_telos
oc_learning_course_snapshots            oc_learning_video_progress
oc_learning_course_videos
oc_learning_duel_answers
oc_learning_duel_invites
oc_learning_duel_sessions
oc_learning_epoch_progress
oc_learning_feed_items

Five tables were renamed over the app’s history (in v4.4.2 and again in v5.2.x). The migrations are self-healing, so on an up-to-date install only the new names exist — but if an upgrade ever failed midway, a legacy name may still be sitting there. Include them defensively; DROP TABLE IF EXISTS makes it harmless either way:

oc_learning_q_translations    →  oc_learning_qst_translations
oc_learning_a_translations    →  oc_learning_ans_translations
oc_learning_q_overrides       →  oc_learning_course_question_overrides
oc_learning_curriculum_scopes →  oc_learning_course_curriculum_scopes
oc_learning_announcements     →  oc_learning_course_announcements

The LIKE 'oc_learning_%' queries below catch both variants automatically.

PostgreSQL:

DO $$
DECLARE t text;
BEGIN
  FOR t IN SELECT tablename FROM pg_tables
           WHERE schemaname = current_schema() AND tablename LIKE 'oc_learning\_%'
  LOOP EXECUTE format('DROP TABLE IF EXISTS %I CASCADE', t); END LOOP;
END $$;

MySQL / MariaDB:

SELECT GROUP_CONCAT(CONCAT('`', table_name, '`') SEPARATOR ', ')
  FROM information_schema.tables
 WHERE table_schema = DATABASE() AND table_name LIKE 'oc\_learning\_%';
-- then: SET FOREIGN_KEY_CHECKS=0; DROP TABLE <paste>; SET FOREIGN_KEY_CHECKS=1;

2. Delete the non-table rows — do not skip this

DELETE FROM oc_migrations    WHERE app   = 'learning';   -- ← critical, see warning
DELETE FROM oc_appconfig     WHERE appid = 'learning';
DELETE FROM oc_preferences   WHERE appid = 'learning';
DELETE FROM oc_jobs          WHERE class LIKE 'OCA\\Learning\\%';
DELETE FROM oc_notifications WHERE app   = 'learning';
DELETE FROM oc_activity      WHERE app   = 'learning';

:warning: oc_migrations is the one that bites. Drop the 54 tables but leave those ~85 rows behind, and a later reinstall believes every migration has already run. It creates nothing, and the app boots into a broken state with no obvious error. If that already happened to you: delete the rows, then occ upgrade.

3. Files — nothing to clean

The app stores no data of its own on disk. Course documents, videos and images are ordinary Nextcloud files in the users’ own folders; the app only references them by path. Removing the app leaves them untouched, which is intended. There is no appdata_*/learning folder.

4. Then remove the app

occ app:remove learning

:warning: Before you run any of this: certificates

If your instance has ever issued a certificate, oc_learning_cert_keys and the issuer entries in oc_appconfig hold the Ed25519 private key of your issuer identity. Deleting it is irreversible: every certificate already handed out becomes permanently unverifiable, including through the public /verify route. There is no way to regenerate the key — a new one produces a different did:web identity and will not validate old signatures.

If that matters to you, export the key material before the oc_appconfig delete, or keep the two cert* tables and the issuer config rows and drop everything else.

What we will add

An occ learning:uninstall command that does all of the above in one transaction — dry-run by default, listing exactly what it would delete, with an explicit confirmation flag to actually execute, and a --keep-certificates escape hatch. I will link the commit here.