how to populate database fields when model changes in django - mysql

I have a django app that is evolving. The model often changes and I use Django South to apply schema migrations.
Sometimes my changes involve populating new values that are added based on sql logic.
For example, added a new boolean flag for currently paying users. I have added the field, applied the migration but now I want to populate the field based on the data from other table to show who is paying.
I know I can do this with a simple sql statement, but my environment is automated and uses CI. I want to push changes and have the flag populated automatically.
How can I accomplish this? With South? With Django?

There is a thing called data migration, this is a perfect use case for it:
Data migrations are used to change the data stored in your database to
match a new schema, or feature.
from south.v2 import DataMigration
from django.conf import settings
class Migration(DataMigration):
def forwards(self, orm):
# update your user's boolean flag here
See an example of a data migration here.
Or, alternatively, you can open your schema migration .py file and populate your field in forwards() method, like this:
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'User.paying'
db.add_column(u'user', 'paying',
self.gf('django.db.models.fields.BooleanField')(default=True),
keep_default=False)
# update your user's boolean flag here
def backwards(self, orm):
# Deleting field 'User.paying'
db.delete_column(u'user', 'paying')

You can add your code in migration script created by south.
If you have updated a model and done schemamigration with south, it will create a script to apply that migration. It will be in appname/migration/00N_some_name.py.
You can add your code in forwards() method in that script at the end after schema alteration is done.

Related

SilverStripe: Getting "you need to change the ClassName before you can write it" after update files to use namespaces

I'm getting this exception when trying to ->write() a DataObject called 'ModelSheet', it says the name should be Models\ModelSheet instead of ModelSheet only (i am under the same namespace (Models) and even try with an use statement)
Hi Guilherme and welcome to stackoverflow,
it seems that the ClassName saved to your database record does not match your PHP classname.
When changing classnames (adding or changing a namespace is changing the classname), you need to update the database to reflect this changes, as the classname is saved in the DB, so Silverstripe knows which PHP-Object is related to the data record.
If you used Silverstripe's upgrader tool, you should have an .upgrade.yml in your module's directory (e.g. in app or mysite). If not, you can add it manually (see e.g. https://github.com/wernerkrauss/silverstripe-onepage/blob/master/.upgrade.yml as a random example). The structure is like
mappings:
OldClassName: My\Namespace\NewClassname
After that all you need is to run dev/build/?flush and your database should be updated.

Is it possible to include a ForeignKey inside a JSONField schema? How else can I effect this?

I am building an app in Django that allows users to build their own forms and in effect customise dynamic models.
After much research, I've decided to effect this through Django, PostgreSQL and JSONFields where one model holds the schema and another holds the record data:
class = Template(models.Model):
schema = JSONField(null=True) # Schema for the form/model
class = DynamicModel(models.Model):
data = JSONField(null=True) # Corresponding data for the form/model
template = models.ForeignKey(Template, null=True,
blank=False, on_delete=models.SET_NULL)
This means users can define their own model templates and I can hold different records using that template in another model.
The idea is to parse the template.schema JSONField to display editable forms using jQuery and to store the output as dynamicmodel.data JSONField. Validations are passed on the client side.
However, this comes with the drawback if I want to allow users to include ForeignKey lookups in their models. For example, say they wanted to add a choice box that offered selections from different customer.ids in a Customer(models.Model) class.
Without hardcoding the ForeignKey directly into the DynamicModel class (which would defeat the point of the exercise) can you think of a way I can achieve this?

Azure Pipeline - Importing Taskgroup via json always creates a new one instead of changing the existing

I have created a Task Group in Azure Pipeline via the GUI.
Then, I exported the JSON.
Next, I have changed the inputs in the json.
Afterward, I wanted to import this new json to change the existing TaskGroup.
Result:
It didn't update the existing TaskGroup, instead, it created a new task group called the same but as postfix " - Copy".
Analyzed:
When I downloaded the new imported Task Group I have seen that the value of Id has changed.
Anyway, I could not found a way to update the existing TaskGroup, what do I have to change in my Json in order to alter and not to create a new one?
Thanks!
Try using the Taskgroups Update API.

How to avoid triggering unique validator on model edition?

I'm using Flask, SQLAlchemy and WTForms. I have a number of properties in my model object which are marked as unique and nullable=False. This works fine when creating a new row in the database but when I try to edit an existing object the validator on WTForms fails with
{'aproperty': [u'Already exists.']}
How can I make this validation pass without having to change my data model?
Update
Following the documentation was of no use to me.
You need to associate the existing record with the form. Otherwise the validator has no way of knowing that you're updating an existing record instead of creating a new one. Something like the following should do the trick:
current_obj = ...
form = MyForm(request.form, obj=current_obj)
form.validate_on_submit():
form.populate_obj(current_obj)

Django - Add rows to MySQL database

So I already have a database setup with a few columns and a few rows already inserted in. I'm trying to create a view that you would just input information into a form and press Submit, then a row would be added to the MySQL database with the information you just typed in.
I believe you can do this with admin, but I would like to try without admin and I'm not sure if this is possible? I've been using the MySQL commandline to add rows as of now..
Of coures this is possible this is a building block for data driven websites. You can use a ModelForm as Daniel suggested (they offer built in validation and HTML markup for FREE) to easily map your model to a front end form. It would probably be beneficial to start with django tutorial or documentation first.
At the the very basic, all you have to do is instantiate your model
new_entry = YourModel(name='me', age='222', about='stackoverflow')
then save it
new_entry.save()
This adds it as a new row to your db.
https://docs.djangoproject.com/en/dev/topics/db/models/
Why would it not be possible?
You probably want a modelform (but see the general form introduction first).
Try out this example of Generic Views: http://postneo.com/2005/08/17/django-generic-views-crud (assumes a model named Task)
With Generic Views you get Insert, Update and Delete for free without any real work. give it a try and let me know what you think.
from django.conf.urls.defaults import *
info_dict = {
'app_label': 'tasks',
'module_name': 'tasks',
}
urlpatterns = patterns('',
(r'^tasks/create/?$', 'django.views.generic.create_update.create_object', info_dict ),
(r'^tasks/update/(?P<object_id>\d+)/?$', 'django.views.generic.create_update.update_object', info_dict),
(r'^tasks/delete/(?P<object_id>\d+)/?$', 'django.views.generic.create_update.delete_object', info_dict ),
)
Django Docs: https://docs.djangoproject.com/en/1.2/ref/generic-views/#create-update-delete-generic-views