Setting a model attribute to some sql value in Django - django

I have a model called job and I want to set a datetime attribute (started_time) to MySQL now() value. how can I do that in Django?
I don't want to use the model auto_now or auto_now_add methods, since I have other applications who share the same DB and I don't want to handle timezones, thus I want to delegate that to MySQL

Don't use auto_now/auto_add_now, they are problematic. Instead, do this:
started_time = models.DateTimeField(default=datetime.utcnow)
-- assuming that you're working with timestamps in UTC.

Use MySQL trigger.

Related

django modified_at field with database level auto update

I need to have modifed_at fields in my Django project. A field that updates every time a row updates in the database, despite where the update comes from: through calling .save() or through queryset.update() or even when updates happen in the database directly and not from the Django app.
there is an auto_now property that does not solve my problem according to this SO question(based on Django document).
other SO questions(like this and this) ask the same thing, update instance at every change not only .save()
This problem can be solved using triggers as said here but this way we need to write the same trigger for every modifed_at field in models.
as discussed in this Django ticket this problem will not be addressed and solved in Django. even the suggested patch only updates the instance if it changes via Django.
the only way that comes to my mind is to do something like this in a mixin. a mixin that when inherited creates a trigger for fields with auto_now=True. maybe change SQL when Django creates the model creation SQL. but I don't know how to implement this.
so I have two questions:
what is the best way to achieve database-level updates for modified_at fields
If my suggested way is the best option how to implement it?
I would like to have a database-agnostic solution but FYI currently I'm using PostgreSQL.
As you said, if you use triggers you'd have to create a trigger for every table.
To make this easier however you could create a migration file to create/destroy the trigger. Here's an example.
Then it would just be a matter of copy-pasting that migration file whenever you create a new model.
Edit:
You could even override the makemigrations command to automatically add the creation of the trigger step to the operations of the initial migrations file. Here's an answer that shows how to override management commands.
So you can use the Django's auto_now field for that.
If you want to auto populate the DateTimeField when creating a new object you can do this: created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("created_at"))
If you want to update the field anytime the object is updated you can do this instead: updated_at = models.DateTimeField(auto_now=True, verbose_name=_("updated at"))
For more info you can refer here

Does Django support setting the beginning value for an id column?

I have seen several questions and answers on SO, most were three years old or older and I looked at the Django documentation (hoping I didn't miss it). I have to have a 9+ digit number for an id. Most responses were to do this at the database. I am guessing that means to create the model in Django and then go back to the database and change the id column Django created with a new starting/next value attribute on the column.
If not how can I create a database table from Django, Code First, that allows me to create a table with an id column that starts at 100000000? And, it be done with the stock model object methods in Django. I don't really want to do a special hack. If that is the case, I can go the database and fix the column. I was trying to adhere to the Code First ideas of Django (though I prefer database first, and am afraid using inspectdb will make a mess.)
Edit: I didn't want to use UUID. I believe BigAutoField is best.
You should be able to do this in two steps:
1 - Specify your primary key explicitly using primary_key=TRUE in your model definition. See the Django docs for more info. You can then specify BigAutoField or whatever other type you want for the primary key.
2A - If you're populating the database up front, just set pk: 100000000 in your fixture.
OR
2B - If you're not populating the database up front, use Django Model Migration Operations RunSQL as detailed here. For your SQL use ALTER TABLE tableName AUTO_INCREMENT=100000000.

SqlAlchemy changes in Model description not applied in DB

I am currently developing a server using Flask/SqlAlchemy. It occurs that when an ORM model is not present as a table in the database, it is created by default by SqlAlchemy.
However when an ORM class is changed with for instance an extra column is added, these changes do not get saved in the database. So the extra column will be missing, every time I query. I have to adjust my DB manually every time there is a change in the models that I use.
Is there a better way to apply changes in the models during development? I hardly think manual MySql manipulation is the best solution.
you can proceed as the following:
new_column = Column('new_column', String, default='some_default_value')
new_column.create(my_table, populate_default=True)
you can find more details about sqlalchemy migration in: https://sqlalchemy-migrate.readthedocs.org/en/latest/changeset.html

Initial value for django model autofield

I'm creating an app in django that will eventually be filled with data from its predecessor. I'd like to have certain models start their auto-increment counter at 10000 to differentiate this data in advance and keep the pk accounting consistant. How can I do this in the model? AutoField doesn't seem to take parameters that would let me do this.
This isn't a question about Django. AutoField is simply a representation of the underlying database's autoincrement property, and Django doesn't control it. Depending on your database backend, you might be able to reset the autoincrement start value: look at your db's documentation for details.

Using custom sql in Django

Is there a way to run a custum SQL statement in Django? I have some timestamp fields in my database that have timezone information. Normally you could just enter the time in a format like: 2010-7-30 15:11:22 EDT and in my case postgresql will figure it out. But in Django it treats timestamps as Datetimes which don't store timezone information so I can't just update the model object with this string and save it. Any ideas?
I somehow must have missed the link in the documentation that covers this: http://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly.