Add properties to Google Datastore entity dynamically - python-2.7

I have a below use case:
I have a method that accepts a list of strings. For each of the strings, I need to create a property under an existing google data store entity A
Example: I have an existing entity Person with properties fname and lname.
If the input list has strings - address, city, I need to update the entity Person to include these new properties address and city.
I'm coding this use case in Python. Any suggestions on how I can achieve this?

So the best way to do this is to let your class inherit ndb.Expando. The difference between Expando and Model is that you can always add attributes to an Expando entity and be able to store it in the Datastore.
Knowing this, there are several ways to proceed, but I am guessing you’re also going to need to use Python’s setattr(object, name, value) method to pass the attribute name from a string.

Take a look at the Expando model class: https://cloud.google.com/appengine/docs/standard/python/ndb/creating-entity-models#creating_an_expando_model_class
class Person(ndb.Expando):
pass
person = Person(fname='some', lname='body')
person_key = person.put()
...
person = person_key.get()
person.city = 'San Francisco'
person.address = '1234 Main St.'
person.put()

Related

How can I accept user input from an NSTextField to instantiate a new object using the stringValue as the variable name?

For example, I have a class "Person", with all its member variables.
I have a UI with an NSTextField and a Submit button. When the user enters a name in the text field and clicks submit, a new "person" object is instantiated, so that
let (NSTextField.stringValue) = Person(name: NSTextField.stringValue)
The idea is to have these "Person" objects stored in an array of objects for later reference and modification.
Alternatively, I have considered of course that each Person object has a string variable "Name", so that creating a new object with the name of another existing object doesn't overwrite anything currently instantiated--but in that case, I need a way to iterate generic names like person1, person2, person3. I'm unable to find anything about how to automate that process either, however.
Whenever you start to think "I need to somehow dynamically create new variables", don't. You probably don't need to do that. Most of the times, you need a kind of data structure.
Here, you want variables with custom names. You should probably use a dictionary. A dictionary is like a real dictionary, you have keys and values. Each key correspond to a value and keys cannot contain duplicates.
A dictionary with String as keys and Person as values should do the job:
var myDictionary = [String: Person]()
Now, instead of doing this:
let (NSTextField.stringValue) = Person(name: NSTextField.stringValue)
you do
myDictionary[NSTextField.stringValue] = Person(name: NSTextField.stringValue)
To access a person, do this:
myDictionary["Tom"]
For more info, see the "Dictionaries" section of this; https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html

Different ModelField handling

I have a scenario where a user need to enter a type of contribution. It can be cash or material. Based on his contribution type, I need to store the cash in IntegerField or material in CharField. How can I do it without making two fields in the model and leaving one always as empty field.
class Contribution(models.Model):
CONTRIBUTION_TYPE_CASH = "cash"
CONTRIBUTION_TYPE_MATERIAL = "material"
CONTRIBUTION_TYPE_CHOICES = [
(CONTRIBUTION_TYPE_CASH, _("cash")),
(CONTRIBUTION_TYPE_MATERIAL, _("material"))
]
contributor = models.ForeignKey(Contributor, related_name="donor", verbose_name=_("contributor"))
type = models.CharField(max_length=20, choices=CONTRIBUTION_TYPE_CHOICES, verbose_name=_("contribution type"))
First variant, keep a single CharField and make sure you properly validate input depending on type. You will have to deal with strings all the time, even if the actual value is a number.
Second variant, use model inheritance and define two different models, one for material contributions and another for cash contributions. You can use an abstract parent in which case you'd have to manually merge the two querysets for getting a global contribution list. Or you could use a concrete parent and use a third party package such as django_polymorphic to seamlessly deal with inherited instances. Either way you'd have to create the apropriate model instance in your backend, even if you use the same dynamic form in your frontend.

Change Django model relations without saving them

I want to change properties from related models of a certain model, but I don't want to save them, I just want to change them temporarily.
Take for example these models:
class Duck(models.Model):
name = models.StringField()
class Duckling(models.Model):
name = models.StringField()
parent = models.ForeignKey(Duck, related_name='children')
Now assume there is some data in the database, then when you try this:
for duckling in some_duck.children.all():
duckling.name = 'test-to-change-name'
for duckling in some_duck.children.all():
print(duckling.name)
In the second for loop it will print the original names and not the names we set in the first for loop. If you would save() them in the first for loop, it would work, but I want to change their names temporarily, just for this process.
Does anyone have an idea if this might be possible somehow? I was thinking of maybe overwriting some_duck.children, but then I would need to create a RelatedManager object myself, which is kind of weird and probably hacky. I hope there are better ways.
Edit: I want it to be updated on the some_duck object, so that when you access some_duck.children that you get the updated data over there.
How about converting the children queryset to a list?
children = list(some_duck.children.all())
for duckling in children:
duckling.name = 'test-to-change-name'
for duckling in children:
print(duckling.name)

JPQL 2.0 - query entities based on superclass entity field

I have Entity (not MappedSuperclass) Person (with id, name, surname).
I also have Entity Employee extends Person (with other attributes, unimportant).
Inheritance Strategy is single table.
Now I want to create a namedQuery like this:
SELECT emp FROM Employee emp WHERE emp.name = ?1
In the IDE I get:
the state field path emp.name cannot be resolved to a valid type
I think the problem is that the attribute belongs to the superclass entity.
So far, I haven't found any solution other than using the TYPE operator to perform a selective query on Employee instances.
I'd like to perform the query above. Is that possible?
I'm on EclipseLink/JPA 2.0
Your JPQL seems valid. Did you try it at runtime? It could just be an issue with your IDE.
(include your code)
Person has to be #MappedSuperclass.
http://www.objectdb.com/api/java/jpa/MappedSuperclass
Furthermore, you should use named parameters, e.g. :name instead of ?...

Clean approach to store Key-Value "properties"?

Let say I have one model for cars. Each car has attributes: color, size, weight, etc... I want users to allow the creation of new attributes for each car objects. However I want to share "attributes" so that the attribute "size" only exists once in the db but values exist for each object where users have added them.
My old approach were two models: Car, KeyValue(key: String, value:String) and Car had a 1:m relationship to KeyValue.
Now, to ensure my above constraint I thought of the following:
Three objects: Car, Key, Value
Value(Key: Key)
Car (1:m relation to Value)
However, this reverse approach works very well but does not look "clean" to me. Therefore, I'd like to ask whether a cleaner approach is possbile.
i read this
http://www.craigkerstiens.com/2012/06/11/schemaless-django/
i haven't used this but i think it's ok.
a less complex approach is
django-picklefield
http://pypi.python.org/pypi/django-picklefield/
i hope this can help you
If your "choices" are malleable, i.e. they can be added to, edited, or deleted from, then the choice should be it's own model. For example:
class Color(models.Model):
name = models.CharField(max_length=50)
class Car(models.Model):
color = models.ForeignKey(Color, related_name='cars')
You should have Cars and CarModels
A CarModel has two list of properties. One that has the "PerModel" attributes for all cars of that models (That means all the cars of that model have the same value), and another one (just the names) of the properties that each car can have a different value "PerCar".
CarModel
{
KeyValue(key: String, value:String) propertyValuesPerModel;
List(String) propertyNamesPerCar;
}
Car
{
CarModel model;
KeyValue(key: String, value:String) propertiesPerCar; //Keys can only be those that appear on model.propertyNamesPerCar
}