Opened 4 years ago
Closed 4 years ago
#32171 closed Uncategorized (invalid)
Unable to use ProjectState and ModelState correctly to make changes to MySQL
Reported by: | Ganesh Bhat | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 3.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I am using ProjectState to migrate to a new attributes of a table. I am trying to understand the ModelState and ProjectState using of migrations API in Django 3.0.3/3.1.x.
I am unable to migrate to the new state which has new fields. Can someone help me with the ProjectState and ModelState usage of what to apply for new model_definition migration to work? The following code does not migrate to DB but doesnt give any error.
I want to migrate from a DB table state to another state and there are some metadata _meta.
The current DB state model_state.fields is:
[('id', <django.db.models.fields.AutoField>)]
The future DB state model_state.fields after adding fields_attrs migrations should be this using the models_definition:
[('id', <django.db.models.fields.AutoField>), ('name', <django.db.models.fields.CharField>)]
This is the code I am using:
from django.db.migrations.state import ProjectState
from django.db.migrations.migration import Migration
from django.db.migrations.state import ModelState
from django.db.migrations import operations
# model_definition is coming from a function as the following object
model_definition = {'module': 'testmodule', 'app_label': 'testmodule', 'unicode': <function ModelScript.model_create_config.<locals>.<lambda> at 0x000002047275FF70>, 'attrs': {'name': <django.db.models.fields.CharField>}, 'doc': 'SampleModel(id)', '_meta': <Options for SampleModel>, 'DoesNotExist': <class 'testmodule.SampleModel.DoesNotExist'>, 'MultipleObjectsReturned': <class 'testmodule.SampleModel.MultipleObjectsReturned'>, 'id': <django.db.models.query_utils.DeferredAttribute object at 0x00000204727F9430>, 'objects': <django.db.models.manager.ManagerDescriptor object at 0x00000204727F9490>}
model_state = ModelState.from_model(model_definition)
# field_attrs are all the new fields to be migrated
for k,v in field_attrs.items():
model_state.fields.append((k, v))
# Create a fake migration with the CreateModel operation
cm = operations.CreateModel(name=model_state.name, fields=model_state.fields)
migration = Migration("fake_migration", model_state.app_label)
migration.operations.append(cm)
# SHOULD ProjectState be used for the new definition to be APPLIED to DB and HOW?
state = ProjectState()
with db_conn.schema_editor(collect_sql=True, atomic=migration.atomic) as schema_editor:
# Following create_model also doesnot migrate to Mysql DB
# Gives a Table exists Error even with root user of mysql
# schema_editor.create_model(model_definition)
# Following doesnot migrate to the new required state
state = migration.apply(state, schema_editor, collect_sql=True)
# Following gives atomic transaction error if used along with atomic
# following commit commented gives no error but doesnt migrate
# db_conn.commit()
I have read this and using How to programmatically generate the CREATE TABLE SQL statement for a given model in Django?
I did try the test cases of Django and it didn't work programmatically. Do I have to use addfield categorically? Unsure of how to get this working. Both projectstate and model_create way is not working. I am probably using this wrong or I am missed something. Any help or resource is welcome on this.
Please don't use Trac as a support channel. Closing per TicketClosingReasons/UseSupportChannels.