How to split fixtures

hii,
i have a doctype for courses which contains 40000+ course details so it shows error while exporting fixtures, is there any way to split the course fixtures into two or three parts.
this is the error which shows while exporting fixtures

Traceback with variables (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
      mod_name = 'frappe.utils.bench_helper'
      alter_argv = True
      mod_spec = ModuleSpec(name='frappe.utils.bench_helper', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f9ef6ebfcd0>, origin='/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py')
      code = <code object <module> at 0x2173d30, file "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 1>
      main_globals = {'__name__': '__main__', '__doc__': None, '__package__': 'frappe.utils', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f9ef6ebfcd0>, '__spec__': ModuleSpec(name='frappe.utils.bench_helper', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f9ef6ebfcd0>, origin='/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py'), '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py', '__cached__': '/home/frappe/frappe-bench/apps/frappe/frappe/utils/__pycache__/bench_helper.cpython-311.pyc', 'importlib': <module 'importlib' from '/usr/lib/python3.11/importlib/__init__.py'>, 'json': <module 'json' from '/usr/lib/python3.11/json/__init__.py'>, 'os': <module 'os' (frozen)>, 'traceback': <module 'traceback' from '/usr/lib/python3.11/traceback.py'>, 'warnings': <module 'warnings' from '/usr/lib/python3.11/warnings.py'>, 'Path': <class 'pathlib.Path'>, 'de...
  File "<frozen runpy>", line 88, in _run_code
      code = <code object <module> at 0x2173d30, file "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 1>
      run_globals = {'__name__': '__main__', '__doc__': None, '__package__': 'frappe.utils', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f9ef6ebfcd0>, '__spec__': ModuleSpec(name='frappe.utils.bench_helper', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f9ef6ebfcd0>, origin='/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py'), '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py', '__cached__': '/home/frappe/frappe-bench/apps/frappe/frappe/utils/__pycache__/bench_helper.cpython-311.pyc', 'importlib': <module 'importlib' from '/usr/lib/python3.11/importlib/__init__.py'>, 'json': <module 'json' from '/usr/lib/python3.11/json/__init__.py'>, 'os': <module 'os' (frozen)>, 'traceback': <module 'traceback' from '/usr/lib/python3.11/traceback.py'>, 'warnings': <module 'warnings' from '/usr/lib/python3.11/warnings.py'>, 'Path': <class 'pathlib.Path'>, 'de...
      init_globals = None
      mod_name = '__main__'
      mod_spec = ModuleSpec(name='frappe.utils.bench_helper', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f9ef6ebfcd0>, origin='/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py')
      pkg_name = 'frappe.utils'
      script_name = None
      loader = <_frozen_importlib_external.SourceFileLoader object at 0x7f9ef6ebfcd0>
      fname = '/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py'
      cached = '/home/frappe/frappe-bench/apps/frappe/frappe/utils/__pycache__/bench_helper.cpython-311.pyc'
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 114, in <module>
    main()
      ...skipped... 27 vars
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 20, in main
    click.Group(commands=commands)(prog_name="bench")
      commands = {'frappe': <Group frappe>, 'get-frappe-commands': <Command get-frappe-commands>, 'get-frappe-help': <Command get-frappe-help>}
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
      self = <Group None>
      args = ()
      kwargs = {'prog_name': 'bench'}
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
      self = <Group None>
      args = ['frappe', '--site', 'rawscholar1.frappe.cloud', 'migrate', '--skip-search-index']
      prog_name = 'bench'
      complete_var = None
      standalone_mode = True
      windows_expand_args = True
      extra = {}
      ctx = <click.core.Context object at 0x7f9ef59adc90>
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
      self = <Group None>
      ctx = <click.core.Context object at 0x7f9ef59adc90>
      _process_result = <function MultiCommand.invoke.<locals>._process_result at 0x7f9ef6000e00>
      args = ['migrate', '--skip-search-index']
      cmd_name = 'frappe'
      cmd = <Group frappe>
      sub_ctx = <click.core.Context object at 0x7f9ef6092e10>
      __class__ = <class 'click.core.MultiCommand'>
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
      self = <Group frappe>
      ctx = <click.core.Context object at 0x7f9ef6092e10>
      _process_result = <function MultiCommand.invoke.<locals>._process_result at 0x7f9ef6000d60>
      args = []
      cmd_name = 'migrate'
      cmd = <Command migrate>
      sub_ctx = <click.core.Context object at 0x7f9ef59aded0>
      __class__ = <class 'click.core.MultiCommand'>
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
      self = <Command migrate>
      ctx = <click.core.Context object at 0x7f9ef59aded0>
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
      _Context__self = <click.core.Context object at 0x7f9ef59aded0>
      _Context__callback = <function migrate at 0x7f9ef5956e80>
      args = ()
      kwargs = {'skip_search_index': True, 'skip_failing': False}
      ctx = <click.core.Context object at 0x7f9ef59aded0>
  File "/home/frappe/frappe-bench/env/lib/python3.11/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context(), *args, **kwargs)
      args = ()
      kwargs = {'skip_search_index': True, 'skip_failing': False}
      f = <function migrate at 0x7f9ef5956c00>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/__init__.py", line 29, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
      ctx = <click.core.Context object at 0x7f9ef59aded0>
      args = ()
      kwargs = {'skip_search_index': True, 'skip_failing': False}
      profile = False
      f = <function migrate at 0x7f9ef5956b60>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py", line 616, in migrate
    ).run(site=site)
      context = {'sites': ['rawscholar1.frappe.cloud'], 'force': False, 'verbose': False, 'profile': False}
      skip_failing = False
      skip_search_index = True
      activate_by_import = <module 'traceback_with_variables.activate_by_import' from '/home/frappe/frappe-bench/env/lib/python3.11/site-packages/traceback_with_variables/activate_by_import.py'>
      SiteMigration = <class 'frappe.migrate.SiteMigration'>
      site = 'rawscholar1.frappe.cloud'
  File "/home/frappe/frappe-bench/apps/frappe/frappe/migrate.py", line 187, in run
    self.post_schema_updates()
      self = <frappe.migrate.SiteMigration object at 0x7f9ef3a39650>
      site = 'rawscholar1.frappe.cloud'
      filelock = <function filelock at 0x7f9ef3748fe0>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/migrate.py", line 52, in wrapper
    raise e
      args = (<frappe.migrate.SiteMigration object at 0x7f9ef3a39650>,)
      kwargs = {}
      method = <function SiteMigration.post_schema_updates at 0x7f9ef3748b80>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/migrate.py", line 44, in wrapper
    ret = method(*args, **kwargs)
      args = (<frappe.migrate.SiteMigration object at 0x7f9ef3a39650>,)
      kwargs = {}
      method = <function SiteMigration.post_schema_updates at 0x7f9ef3748b80>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/migrate.py", line 140, in post_schema_updates
    sync_fixtures()
      self = <frappe.migrate.SiteMigration object at 0x7f9ef3a39650>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/fixtures.py", line 22, in sync_fixtures
    import_fixtures(app)
      app = 'rawscholar'
      apps = ['frappe', 'raven', 'frappe_whatsapp', 'rawscholar']
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/fixtures.py", line 41, in import_fixtures
    import_doc(file_path)
      app = 'rawscholar'
      fixtures_path = '/home/frappe/frappe-bench/apps/rawscholar/rawscholar/fixtures'
      fixture_files = ['courses.json', 'workspace.json', 'number_card.json', 'attachment_type.json', 'custom_docperm.json', 'countries.json', 'qualification_type.json', 'role.json', 'university.json']
      fname = 'courses.json'
      file_path = '/home/frappe/frappe-bench/apps/rawscholar/rawscholar/fixtures/courses.json'
  File "/home/frappe/frappe-bench/apps/frappe/frappe/core/doctype/data_import/data_import.py", line 265, in import_doc
    import_file_by_path(
      path = '/home/frappe/frappe-bench/apps/rawscholar/rawscholar/fixtures/courses.json'
      pre_process = None
      files = ['/home/frappe/frappe-bench/apps/rawscholar/rawscholar/fixtures/courses.json']
      f = '/home/frappe/frappe-bench/apps/rawscholar/rawscholar/fixtures/courses.json'
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/import_file.py", line 146, in import_file_by_path
    import_doc(
      path = '/home/frappe/frappe-bench/apps/rawscholar/rawscholar/fixtures/courses.json'
      force = True
      data_import = True
      pre_process = None
      ignore_version = None
      reset_permissions = True
      docs = [{'branch': 'Dental Anatomy', 'course': 'Dental Nursing', 'docstatus': 0, 'doctype': 'Courses', 'duration': '24 Months', 'exam_accepted': None, 'fee': '₹12.37 L/yr', 'level': 'Diploma', 'mode': 'Full time', 'modified': '2024-06-18 13:53:55.754267', 'name': 'COR-0001', 'university': 'Trinity College Dublin', '__islocal': 1}, {'branch': 'History', 'course': 'BA Hons History of Art and Architecture JH', 'docstatus': 0, 'doctype': 'Courses', 'duration': '48 Months', 'exam_accepted': None, 'fee': '₹18.00 L/yr', 'level': 'UG', 'mode': 'Full time', 'modified': '2024-06-18 13:53:55.816026', 'name': 'COR-0002', 'university': 'Trinity College Dublin', '__islocal': 1}, {'branch': 'Foreign Language', 'course': 'BA Hons German JH', 'docstatus': 0, 'doctype': 'Courses', 'duration': '48 Months', 'exam_accepted': None, 'fee': '₹18.51 L/yr', 'level': 'UG', 'mode': 'Full time', 'modified': '2024-06-18 13:53:55.944796', 'name': 'COR-0003', 'university': 'Trinity College Dublin', '__islocal': 1}, {'branch...
      calculated_hash = 'f0835a61f7af98bd7fe605be062860ba'
      doc = {'branch': 'History', 'course': 'BA History and Politics', 'docstatus': 0, 'doctype': 'Courses', 'duration': '36 Months', 'exam_accepted': None, 'fee': '₹21.50 L/yr', 'level': 'UG', 'mode': 'Full time', 'modified': '2024-06-20 16:52:46.621625', 'name': 'COR-33335', 'university': 'University of Reading, Reading', '__islocal': 1}
      db_modified_timestamp = datetime.datetime(2024, 6, 20, 16, 52, 46, 621625)
      is_db_timestamp_latest = True
      new_modified_timestamp = '2024-06-20 16:52:46.424876'
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/import_file.py", line 231, in import_doc
    delete_old_doc(doc, reset_permissions)
      docdict = {'branch': 'History', 'course': 'BA History and Politics', 'docstatus': 0, 'doctype': 'Courses', 'duration': '36 Months', 'exam_accepted': None, 'fee': '₹21.50 L/yr', 'level': 'UG', 'mode': 'Full time', 'modified': '2024-06-20 16:52:46.621625', 'name': 'COR-33335', 'university': 'University of Reading, Reading', '__islocal': 1}
      data_import = True
      pre_process = None
      ignore_version = None
      reset_permissions = True
      path = '/home/frappe/frappe-bench/apps/rawscholar/rawscholar/fixtures/courses.json'
      controller = <class 'rawscholar.rawscholar.doctype.courses.courses.Courses'>
      doc = <Courses: COR-33335>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/modules/import_file.py", line 274, in delete_old_doc
    frappe.delete_doc(doc.doctype, doc.name, force=1, ignore_doctypes=ignore, for_reload=True)
      doc = <Courses: COR-33335>
      reset_permissions = True
      ignore = []
      old_doc = <Courses: COR-33335>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 1392, in delete_doc
    return frappe.model.delete_doc.delete_doc(
      doctype = 'Courses'
      name = 'COR-33335'
      force = 1
      ignore_doctypes = []
      for_reload = True
      ignore_permissions = False
      flags = None
      ignore_on_trash = False
      ignore_missing = True
      delete_permanently = False
      ...skipped... 1 vars
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/delete_doc.py", line 154, in delete_doc
    delete_for_document(doc)
      doctype = 'Courses'
      name = 'COR-33335'
      force = 1
      ignore_doctypes = []
      for_reload = True
      ignore_permissions = False
      flags = None
      ignore_on_trash = False
      ignore_missing = True
      delete_permanently = False
      is_virtual = 0
      names = ['COR-33335']
      doc = <Courses: COR-33335>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/global_search.py", line 462, in delete_for_document
    frappe.db.delete("__global_search", {"doctype": doc.doctype, "name": doc.name})
      doc = <Courses: COR-33335>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py", line 1273, in delete
    return query.run(**kwargs)
      self = <frappe.database.mariadb.database.MariaDBDatabase object at 0x7f9ef374ef90>
      doctype = '__global_search'
      filters = {'doctype': 'Courses', 'name': 'COR-33335'}
      debug = False
      kwargs = {'debug': False}
      query = DELETE FROM `__global_search` WHERE `doctype`='Courses' AND `name`='COR-33335'
  File "/home/frappe/frappe-bench/apps/frappe/frappe/query_builder/utils.py", line 87, in execute_query
    result = frappe.db.sql(query, params, *args, **kwargs)  # nosemgrep
      query = 'DELETE FROM `__global_search` WHERE `doctype`=%(param1)s AND `name`=%(param2)s'
      args = ()
      kwargs = {'debug': False}
      child_queries = []
      params = {'param1': 'Courses', 'param2': 'COR-33335'}
      execute_child_queries = <function patch_query_execute.<locals>.execute_child_queries at 0x7f9ef37f20c0>
      prepare_query = <function patch_query_execute.<locals>.prepare_query at 0x7f9ef37f2160>
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py", line 214, in sql
    self.check_transaction_status(query)
      self = <frappe.database.mariadb.database.MariaDBDatabase object at 0x7f9ef374ef90>
      query = 'DELETE FROM `__global_search` WHERE `doctype`=%(param1)s AND `name`=%(param2)s'
      values = {'param1': 'Courses', 'param2': 'COR-33335'}
      as_dict = 0
      as_list = 0
      debug = False
      ignore_ddl = 0
      auto_commit = 0
      update = None
      explain = False
      run = True
      pluck = False
      as_iterator = False
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py", line 436, in check_transaction_status
    raise frappe.TooManyWritesError(msg)
      self = <frappe.database.mariadb.database.MariaDBDatabase object at 0x7f9ef374ef90>
      query = 'DELETE FROM `__global_search` WHERE `doctype`=%(param1)s AND `name`=%(param2)s'
      msg = '<br><br>Too many changes to database in single action.<br>The changes have been reverted.<br>'
frappe.exceptions.TooManyWritesError: <br><br>Too many changes to database in single action.<br>The changes have been reverted.<br>

can anyone explain this error and how to solve it

The last line tells you:

frappe.exceptions.TooManyWritesError: <br><br>Too many changes to database in single action.<br>The changes have been reverted.<br>

A bit above it gives you the file and the line:

File "/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py", line 436, in check_transaction_status

Maybe you could use a loop around a SQL statement using the LIMIT clause, see:

UPDATE:
Well, I guess my answer makes no sense, because deleting doctypes by their names means these might well be single-row deletions, so using LIMIT in a DELETE won’t make a difference.
A loop might still help, but it would need to be built differently. If the names are provided as a list, the list could be split into parts, or maybe commits after a number of deletes need to be inserted. All this might need to take care of concurrency and thus atomicity regarding writing the documents into the exported file.

Hi:

As @Peer well-said, you are facing too many records. But changing core behavior would be challenging … Maybe fixtures is not the best way to manage this.

You can use after_install hook and import data from a .json file or something like that.

def import_data_from_json():
    filepath = 'yourfile.json'
    with open(filepath) as json_file:
        data = json.load(json_file)
        for entry in data:
            frappe.get_doc(entry).insert(ignore_permissions=True)

Just curiosity … 40.000 courses as “static data”?
Hope this helps.