Python PeeWee IntegerField - Default value of unix timestamp - peewee

I would like to manage timestamps in my database using seconds since epoch using a PeeWee IntegerField rather than a DateTimeField. I know that the field definition can take a default value using a callable, but I would need to do something like:
timestamp = IntegerField(default=int(datetime.datetime.now().strftime('%s')))
Which I suppose is incorrect since the default value should not actually invoke the callable.
I also tried wrapping this in a function and passing that function as a callable:
def get_timestamp():
return int(datetime.datetime.now().strftime('%s'))
timestamp = IntegerField(default=get_timestamp)
However this did not work either.
Is there a way to accomplish this, or do I have to retro-fit my data to use DateTimeFields instead?

I see you mentioned that you tried wrapping your function call, I'm surprised that didn't work for you, because it appears to work fine for me:
>>> from datetime import datetime
>>> from peewee import *
>>> db = SqliteDatabase(':memory:')
>>> def get_ts():
... return int(datetime.now().strftime('%s'))
>>> get_ts()
1448471382
>>> class TestModel(Model):
... ts = IntegerField(default=get_ts)
... class Meta:
... database = db
>>> TestModel.create_table()
>>> tm = TestModel.create()
>>> tm.ts
1448471421
>>> ts_from_db = TestModel.get(TestModel.id == tm.id)
>>> ts_from_db.ts
1448471421
The reason you need to wrap it is because the default param takes a callable, and if you pass just the result of a function call, it interprets it as just another static value.

Related

How to get a type from a TypeVar?

Supose that I have:
T = TypeVar('T', bound='Client')
Now, I want a function that gets the type T and returns 'Client', or, yet better a class Client.
How I can get it in Python 3.9?
Thanks.
You can do so via typing_inspect.get_bound from the typing_inspect package. It offers cross-version support for runtime inspection of type annotations:
>>> class Foo: pass
>>> T = TypeVar("T", bound=Foo)
>>> typing_inspect.get_bound(T)
__main__.Foo
>>> T = TypeVar("T", bound="Foo")
>>> typing_inspect.get_bound(T)
ForwardRef('Foo')
When bound is set to a string, the returned value is a "forward reference". I don't think there's currently a public API to evaluate that to a concrete class. There is a private API that you could use like this:
>>> ref = typing_inspect.get_bound(T)
>>> ref._evaluate(globals(), globals(), set())
__main__.Foo

Implementing functions that include name and symbol

I need to define in Sage some functions with attributes that define
the name of the function
its mathematical/physical symbol
the definition of the function
(and those in combination)
and methods that return
those attributes in LaTeX format
both symbolic and with parameters input and then also
the result of the function on those parameters
An example is something like
>>> somefunction.name
\text{some function}
>>> somefunction.symbol
\mathrm{SF}
>>> somefunction.definition
\mathrm{SF} = 3x + y
>>> somefunction(4, 5)
17
>>> somefunction(4, 5).symbol
\mathrm{SF}\left(4, 5\right)
>>> anotherfunction.name
\text{another function}
>>> anotherfunction.symbol
\mathrm{AF}
>>> anotherfunction.definition
\mathrm{AF} = 2z
>>> anotherfunction('SF')
2(3x + y)
I suppose the way of implementing it is by defining a new class that inherits from the function Class. And perhaps the method names should have _latex appended.
Any ideas?
Thanks in advance,
Chris
You definitely don't want to just use function if you are planning something more interesting. See if the tips for implementing new symbolic functions fits your needs (though this may be overkill). Yes, you definitely want something with a latex attribute/method.

How to get random value from a file in python?

It would have been very gratifying to figure this out by myself but I haven't been able to.
I want to grab a random value from a text file that contains data in the form of a dictionary eg:
{'One': '1111111', 'Two': '2222222', 'Three': '3333333'}
I've tried a few variations, but code is currently:
from random import *
table = open('file.txt')
random_value = random.choice(table.values())
When I try and print 'random_value' (to see if it is working), I get the error:
AttributeError: 'file' object has no attribute 'values'
table is a file object, and thus you want to turn it into a dictionary. Here I use the ast module:
from random import choice # No need to import everything if you're going to use just one function
import ast
table = open('file.txt').read()
mydict = ast.literal_eval(table)
random_value = choice(mydict.values())

Pass enum to ndb.Model field in python

I find How can I represent an 'Enum' in Python? for how to create enum in python. I have a field in my ndb.Model that I want to accept one of my enum values. Do I simply set the field to StringProperty? My enum is
def enum(**enums):
return type('Enum', (), enums)
ALPHA = enum(A="A", B="B", C="C", D="D")
This is fully supported in the ProtoRPC Python API and it's not worth rolling your own.
A simple Enum would look like the following:
from protorpc import messages
class Alpha(messages.Enum):
A = 0
B = 1
C = 2
D = 3
As it turns out, ndb has msgprop module for storing protorpc objects and this is documented.
So to store your Alpha enum, you'd do the following:
from google.appengine.ext import ndb
from google.appengine.ext.ndb import msgprop
class Part(ndb.Model):
alpha = msgprop.EnumProperty(Alpha, required=True)
...
EDIT: As pointed out by hadware, a msgprop.EnumProperty is not indexed by default. If you want to perform queries over such properties you'd need to define the property as
alpha = msgprop.EnumProperty(Alpha, required=True, indexed=True)
and then perform queries
ndb.query(Part.alpha == Alpha.B)
or use any value other than Alpha.B.

If I have a direct reference to a google app engine Property object, how do I get() or set() upon it?

Assume I have a Model class called Bird and a instance of Bird called pigeon. I know I can get all the Properties of Pigeon (or bird) using
properties = pigeon.properties() #Note, Bird.properties() would also work
This returns me a dictionary where the keys are strings that match the name I gave said properties in birds, and the value are actual Property objects. My question is, how do I get or set the value using said property objects. I wish to do this because I want to allow a client to dynamically specify as strings:
1) the key to a Model object
2) a property of said Model object
3) and a value that the afformentioned Property of said Model object might take on
So clearly, I need to first get the Model object, then determine whether said Property exist, and finally get or set it somehow? Is this possible? Thank you.
I played around with App Engine Console, which is great for testing and experimenting. It looks to me like you want to use __set__, with the first argument being your model instance, and the second being the new value. Next you need to put() the instance as usual.
Here is the console session to make it clearer. (Have I mentioned how App Engine Console is awesome?)
>>> from google.appengine.ext import db
>>> class Bird(db.Model):
... name = db.StringProperty()
... can_fly = db.BooleanProperty()
...
>>> def summarize():
... for name in ('Pesto', 'Bobby'):
... count = Bird.all().filter('name =', name).count()
... print 'I found %d birds named %s' % (count, name)
...
>>> summarize()
I found 0 birds named Pesto
I found 0 birds named Bobby
>>> pigeon = Bird(name='Pesto', can_fly=True)
>>> pigeon.put()
datastore_types.Key.from_path('Bird', 41015L, _app=u'con')
>>> summarize()
I found 1 birds named Pesto
I found 0 birds named Bobby
>>> props = pigeon.properties()
>>> props
{'can_fly': <google.appengine.ext.db.BooleanProperty object at 0x46ddd1cc3ddb2268>, 'name': <google.appengine.ext.db.StringProperty object at 0x46ddd1cc3ddb2fe8>}
>>> prop = props['name']
>>> prop
<google.appengine.ext.db.StringProperty object at 0x46ddd1cc3ddb2a68>
>>> prop.__set__(pigeon, 'Bobby')
>>> pigeon.name
'Bobby'
>>> pigeon.put()
datastore_types.Key.from_path('Bird', 41015L, _app=u'con')
>>> summarize()
I found 0 birds named Pesto
I found 1 birds named Bobby
>>> bobby = Bird.all().filter('name =', 'Bobby').fetch(1)[0]
>>> bobby.name
u'Bobby'
If you try the online console demo yourself, be sure to delete my old instances first, as we all share the same data store.

Resources