Datatype not preserved in dictionary - python

Hi I'm having trouble storing a datetime object in a dictionary in python. When I try to retrieve the datetime object to compare with another datetime object the returned object is a str not a datetime.
class Course(models.Model):
StartDate = models.DateTimeField()
dict = {}
myDate = Course.StartDate
dict['date'] = myDate
today = datetime.datetime.today()
if today > dict['date']:
pass
assume Course.StartDate returns a datetime object.

It does look you're missing something in your code here, because what you're trying to do works just fine.
With this model:
class Course(models.Model):
# auto_now_add for convenience when testing
start_date = models.DateTimeField(auto_now_add=True)
I created an object:
>>> c = Course.objects.create()
And created a dictionary:
>>> mydict = {}
Assigned the start_date attribute to a dictionary key:
>>> mydict['date'] = c.start_date
Access the value as a datetime object:
>>> mydict['date']
datetime.datetime(2012, 3, 1, 16, 55, 49, 723208)
And can compare the dictionary value to a datetime object:
>>> datetime.datetime.today() > mydict['date']
True

Related

Convert CharField to String

For a database query with pymysql, I'm getting the model
class MyModel(Model):
id = AutoField()
date1 = CharField()
confirmed = IntegerField()
Getting the date works, but I have to do some calculations with date1. For this, I need to convert it to a datetime object with datetime.strptime().
for model in MyModel.select().where(MyModel.confirmed == 0):
rd = MyModel.date1
date_time_obj = datetime.strptime(rd, '%d.%m.%Y')
The problem is that date1 is a CharField, not a string, so strptime does not work. How can I get the content of the CharField into a string? As the rest of the script works the way it is, ideally it would be in a way that doesn't change the retrieved data.
This issue is that you're accessing the CharField from the class, rather than an instance of the class. Try this instead:
for model in MyModel.select().where(MyModel.confirmed == 0):
rd = model.date1
date_time_obj = datetime.strptime(rd, '%d.%m.%Y')

How to check if a Marshmallow schema's Datetime field is less than today's date?

I have an endpoint that accepts POST method. The POST body contains a DateTime field of format - "%Y-%m-%d %H:%MZ". I need to validate if that datetime is less than current Datetime in UTC. I'm using Marshmallow to validate the request body.
run_datetime = fields.DateTime(format="%Y-%m-%d %H:%MZ")
Are there any inbuilt validators for this case to validate DateTime field. Or should I be writing a custom function for this to compare the run_datetime with today's UTC's datetime.
There is no built-in validator that can solve your particular issue at hand, take a look at the available validators here.
Although, defining your own validator is trivially easy, for your particular case: fields.Datetime will accept an argument named validate which can take a function that returns a bool. For example, I quickly defined a lambda here to validate if the datetime is more recent than "now":
from datetime import datetime
from marshmallow import Schema, fields
NOW = datetime(2020, 11, 23, 14, 23, 0, 579974)
class User(Schema):
id = fields.Integer(required=True)
name = fields.String(required=True)
# Define an arbitrary datetime here like NOW or just use datetime.now()
date_created = fields.DateTime(required=True, validate=lambda x: x > NOW)
# This will succeed
User().load(dict(
id=10,
name="Test",
# Note that this date is more recent than previously defined NOW
date_created="2020-11-23T14:24:40.224965",
))
#{'date_created': datetime.datetime(2020, 11, 23, 14, 24, 40, 224965),
# 'id': 10,
# 'name': 'Test'}
# While this will fail
User().load(dict(
id=10,
name="Test",
# Here the date is one month behind than NOW
date_created="2020-10-23T14:24:40.224965",
))
# ValidationError: {'date_created': ['Invalid value.']}

I want to store datetime in peewee.DateTimeField(), I use datetime.datetime.now() in that field as default but it can't work

this code cannot work and give json serializable error
class Bank(peewee.Model): // create Bank table
bank_id = peewee.PrimaryKeyField()
bank_name = peewee.CharField()
account_no = peewee.CharField()
ifc_code = peewee.CharField()
swift_code = peewee.CharField(null = True)
modify_date = peewee.DateTimeField(default=datetime.datetime.now(),formats=['%Y-%m-%d'])/*date in yyyy-mm-dd formate*/
status = peewee.IntegerField(default = 0)
class Meta:
database = db
This answer is very incorrect - please see my answer below (#coleifer).
The default date that you are providing is not a datetime object. Rather it's a string!
modify_date = peewee.DateTimeField(default=datetime.datetime.now().strftime('%Y-%m-%d'))
type(datetime.datetime.now().strftime('%Y-%m-%d')) --> str
You can pass default current datetime object like this:
date = datetime.datetime.now().strftime('%Y-%m-%d')
need_date = datetime.strptime(date, '%Y-%m-%d')
modify_date = peewee.DateTimeField(default=need_date)
or
peewee.DateTimeField(default=datetime.datetime.now)
It looks like non-timezone aware datetimes work fine, so if you're using UTC then you can store datetime.utcnow() as that returns the current UTC date and time with tzinfo None i.e. as a "naive" datetime object.
I found this solution to store and retrieve the timezone aware field as text, however it's not ideal as the datetime object isn't being stored.
from datetime import datetime
from peewee import *
class TimestampTzField(Field):
"""
A timestamp field that supports a timezone by serializing the value
with isoformat.
"""
field_type = "TEXT"
def db_value(self, value: datetime) -> str:
if value:
return value.isoformat()
def python_value(self, value: str) -> str:
if value:
return datetime.fromisoformat(value)
https://compileandrun.com/python-peewee-timezone-aware-datetime/
If you want to store a date, use the DateField. Also, the default needs to be a callable -- in other words, leave OFF the parentheses!
class Bank(peewee.Model): // create Bank table
bank_id = peewee.PrimaryKeyField()
bank_name = peewee.CharField()
account_no = peewee.CharField()
ifc_code = peewee.CharField()
swift_code = peewee.CharField(null = True)
modify_date = peewee.DateField(default=datetime.date.today)
status = peewee.IntegerField(default = 0)
class Meta:
database = db
When it comes time to serialize this as Json, just use a custom json formatter that can handle python datetime.date objects. This is the proper way. You should always store your data using the appropriate format and worry about presentation (and serialization) in another layer.
It is very simple to extend Python's json serializer to handle unsupported types:
def convert_date(o):
if isinstance(o, datetime.date):
return o.__str__()
json.dumps(my_obj, default=convert_date)

Error - "SQLite DateTime type only accepts Python " "datetime and date objects as input."

I tried to declared a variable contains of Datetime like this
ts1.departure_date = '2012-03-03 10:10:10'
but then I got this error
StatementError: (exceptions.TypeError) SQLite DateTime type only accepts Python datetime and date objects as input.
I wonder what is the correct way to declare a variable with datetime format? Thanks in advance
First import the datetime class:
from datetime import datetime
Then create a datetime object and use that to set your attribute:
ts1.departure_date = datetime(2012, 3, 3, 10, 10, 10)
expiration_year = int(form.expiration_date.data[:4])
expiration_month = int(form.expiration_date.data[5:7])
expiration_date = int(form.expiration_date.data[8:10])
expiration_date =datetime(expiration_year,expiration_month,expiration_date)
Ultra strange error that encountered with SQLAlchemy with both SQLite and Postgres
from datetime import datetime
....
#WORKS
lending_operation = models.LendingOperation(
device_id = device.device_id,
start_using = datetime.now()
)
db.session.add(lending_operation)
db.session.commit()
#DIDN'T WORK
lending_operation = models.LendingOperation(
currency = "USD",
device_id = device.device_id,
start_using = datetime.now()
)
db.session.add(lending_operation)
db.session.commit()
#MODEL: models.py
class LendingOperation(db.Model):
.....
start_using = db.Column(db.DateTime, default=datetime.now )
.....
currency = db.Column(db.DateTime)
Hope it helps, didn't find any info on the exception

How to convert string date in datetime.date format

I want to convert date like Jun 28 in datetime format like 2014-06-28. I tried following code and many more variation which gives me correct output in ipython but I m unable to save the record in database. It throws error as value has an invalid date format. It must be in YYYY-MM-DD format. Can anyone help me to fix this issue ?
Following is the code snippet
m = "Jun"
d = 28
y = datetime.datetime.now().year
m = strptime(m,'%b').tm_mon
if m > datetime.datetime.now().month:
y=y-1
new_date = str(d)+" "+str(m)+" "+str(y)
new_date = datetime.datetime.strptime(new_date, '%b %d %Y').date()
my models.py is as
class Profile(models.Model):
Name = models.CharField(max_length = 256, null = True, blank = True)
Location = models.CharField(max_length = 256, null = True, blank = True)
Degree = models.CharField(max_length = 256, null = True, blank = True)
Updated_on = models.DateField(null = True, blank = True)
Code that saves to model is like
def save_record(self):
try:
record = Profile(Name= indeed.name,
Location = loc,
Degree = degree,
Updated_on = new_date,
)
record.save()
print "Record added"
except Exception as err:
print "Record not added ",err
pass
Thanks in advance
Once you have a date object, you can use the strftime() function to format it into a string.
Let's say new_date is your date object from your question. Then you can do:
new_date.strftime('%Y-%m-%d')
Btw, you can do the same with a datetime object too.
EDIT:
Double check whether your Updated_on field uses DateField or DateTimeField. That will affect whether you use a datetime.date() object or datetime.datetime() object, respectively.
I tried on console:
>>import datetime
>>datetime.datetime.strptime("Jun-08-2013", '%b-%d-%Y').date()
datetime.date(2013, 6, 8)
There are several errors in the code. So solution should be:
m = "Jun"
d = 28
if datetime.datetime.strptime("Aug",'%b').month > datetime.datetime.now().month:
y= (datetime.datetime.now() - relativedelta(years=1)).year #from dateutil.relativedelta import relativedelta
else:
y=datetime.datetime.now().year
new_date = str(m)+"-"+str(d)+"-"+str(y)
new_date = datetime.datetime.strptime(new_date, '%b-%d-%Y').date()
new_date is a date object, so it should be saved to models.DateField() without any problem(including format issues).

Categories

Resources