Django models datetime with timezone UTC+1 saved as UTC+0 - python-3.x

In my django project i have a model where i store data (in my read_date field) with a DateTime field for storing date (with timezone):
class Results(models.Model):
id = models.AutoField(primary_key=True)
device = models.ForeignKey(Device, null=True, on_delete=models.SET_NULL)
proj_code = models.CharField(max_length=400)
res_key = models.SlugField(max_length=80, verbose_name="Message unique key", unique=True)
read_date = models.DateTimeField(verbose_name="Datetime of vals readings")
unit = models.ForeignKey(ModbusDevice, null=True, on_delete=models.SET_NULL)
i setted in settings.py file using timezone:
TIME_ZONE = 'UTC+1'
USE_TZ = True
So, the problem is, when i pass a corrected formatted ditetime with UTC+1 timezone as:
2021-11-12 10:39:59.495396+01:00
in my db i get:
2021-11-12 9:39:59.495396+00
Why my stored value is UTC+0 instead using timezone passed?
So many thanks in advance

All the date-times are stored in the UTC.
It's not a bug it's a feature. The database needs one format to process the DateTime data when sorting, selecting, filtering, etc. So when you are making some SQL requests you can pass a needed timezone for auto converting. For example, your first user in the UTC+1 and you can make requests using this parameter, your another user UTC-9, and the results could be different.

Related

colors = Color.query.all()

Hi I am trying to follow this tutorial to learn how to get pagination in my flask project.
https://betterprogramming.pub/simple-flask-pagination-example-4190b12c2e2e
I am having problems with the following line
"colors = Color.query.all()"
Where does "Color" come from ?
In all the tutorials I have read this form of variable appears but no explanation where it comes from
The Color class is a database model that was implemented with flask-SQLAlchemy. The class can be used to add, remove and query entries in a database table.
The definition of the model is as follows and contains three columns. The ID as a unique key for identification, the name of the color and a date when the database entry was added.
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
# ...
db = SQLAlchemy(app)
class Color(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False, unique=True, index=True)
created_at = db.Column(db.DateTime(timezone=True),
nullable=False, unique=False, index=False,
default=datetime.utcnow)
# ...
To use the database you have to create the necessary tables either via the flask shell or within your code like here.
with app.app_context():
db.create_all()
The flask-SQLAlchemy introductory example and the SQLAlchemy documentation explain more.
I also recommend this series of articles as a good tutorial for flask.
Have fun.

how to get datetime type column data into 'MM/YYYY' format using flask SqlAlchemy in python

I have an column in the database which is datetime type and i have to retrieve date into 'MM/YYYY' format.
what i have to do this in sqlalchemy, python?
my current query is as follow =>
session.query(Model.models.DefineStructureOfTable.Detail.AsOfDate).filter(
Model.models.DefineStructureOfTable.Detail.ID.in_(getId)).all()
currently it gives me result as datetime type date
Please Help!
If your question is how to convert datetime into the format MM/YYYY, you can use strftime.
result.strftime("%m/%Y")
If your question is about how you make the database return a different format, you can't. You can't change the types of the underlying database. But you could change the type to TEXT, and just store the string directly - not recommended in this format because it will be hard to sort.
Alternatively add a method or property to the model to get the datetime in the right format.
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
month_and_year = db.Column(db.DateTime)
#property
def formatted_month_and_year(self):
return self.month_and_year.strftime("%m/%Y")

Query date on datetime stored within jsonfield in Postgres through Django?

I have a Postgres table with a jsonb column containing UTC timestamp data in ISO format like the following:
{
"time": "2021-04-13T20:14:56Z"
}
The Django model for this table looks like:
class DateModel(models.Model):
values = models.JSONField(default=dict)
I need to query the table for all records with a timestamp on a certain date (ignoring time)
I'm looking for a solution similar to the following:
DateModel.objects.filter(values__time__date='2021-04-13')
The other solution I have found is to query for records with date greater than the previous day and less than the next one. This works but I am looking for a way to do it with a single query so the code would be more concise.
Any suggestions?
There's a couple of annotations you need to perform on the queryset to extract the time field and convert it to a datetime.
First you need to extract the time string by using django.contrib.postgres.fields.jsonb.KeyTextTransform
from django.contrib.postgres.fields.jsonb import KeyTextTransform
query = DateModel.objects.annotate(time_str=KeyTextTransform('time', 'values'))
Then you need to convert that string to a datetime using Cast
from django.db.models.functions import Cast
from django.db.models import DateTimeField
query = query.annotate(time=Cast('time_str', output_field=DateTimeField()))
Then you can filter by that annotation
query = query.filter(time__date='2021-04-13')

How do I use flask-sqlalchemy to pass a date and time into a Postgres table

I am using flask-sqlalchemy and flask-wtforms to ask a user to pick a date and time. I then want to pass this date and time as UTC into my PostgreSQL database using flask-sqlalchemy.
My main problem is that I cannot find the documentation that helps me understand the process of the fields I need in my events table and the format I need to pass from my wtform. I have used a .datetimepicker in my HTML and my form.py line looks like this.
eventstart = DateTime('Event Start', validators=[DataRequired()])
I have followed a few examples but if anyone can point me in the right direction, I would be very grateful.
__tablename__ = 'events'
id = db.Column(db.Integer, primary_key=True)
eventname = db.Column(db.String(64), unique=True, index=True)
eventstart = db.Column(db.DateTime, nullable=False)
eventstop = db.Column(db.DateTime, nullable=False)
timeblock = db.Column(db.Integer)
The fields for DateTime are correctly defined in your DB table 'events'.
The format for storing the datetime should be like 2022-03-21 19:04:14.
You can get eventstart into this format or can also use pandas.to_datetime to reformat it which can be stored into the table.

Change SQLAlchemy __tablename__

I am using SQLAlchemy to handle requests from an API endpoint; my database tables (I have hundreds) are differentiated via a unique string (e.g. test_table_123)...
In the code below, __tablename__ is static. If possible, I would like that to change based on the specific table I would like to retrieve, as it would be tedious to write several hundred unique classes.
from config import db, ma # SQLAlchemy is init'd and tied to Flask in this config module
class specific_table(db.Model):
__tablename__ = 'test_table_123'
var1 = db.Column(db.Integer, primary_key=True)
var2 = db.Column(db.String, index=True)
var3 = db.Column(db.String)
class whole_table_schema(ma.ModelSchema):
class Meta:
model = specific_table
sqla_session = db.session
def single_table(table_name):
# collect the data from the unique table
my_data = specific_table().query.order_by(specific_table.level_0).all()
Thank you very much for your time in advance.
You can use reflect feature of SQLAlchemy.
engine = db.engine
metadata = MetaData()
metadata.reflect(bind=engine)
and finally
db.session.query(metadata.tables[table_name])
If you want smoother experience with querying, as previous solution cannot offer one, you might declare and map your tables: tables = {table_name: create_table(table_name) for table_name in table_names}, where create_table constructs models with different __tablename__. Instead of creating all tables at once, you can create them on demand.

Resources