Entity method - setPropertiesFrom - google-app-engine

I am trying to clone an Entity.
Question on Entity method
Entity.setPropertiesFrom(Entity src).
The documentation says
"A convenience method that populates the properties of this Entity with the properties set on the provided Entity. This method transfers information about unindexed properties"
How about indexed properties? Do they get populated as well.
-Aswath

Yes, it transfers all properties. I suspect that the docs mean that if a property is unindexed in the source entity, it will also be marked as unindexed in the target... but I don't know for sure.

Related

How do i model multiple photos (for a Hotel) with schema.org?

I am new to schema.org. Currently i am trying to use it as our internal data model for imports as it offers a good "common ground" for all source systems.
The Hotel schema (https://schema.org/Hotel) offers a "photo" (singular) property, it inherits from Place. It used to have a "photos" (plural) property in the past.
When using schema.org for markup, this would not matter, as i can just mark up multiple elements as "photo".
However, when using it as a data class, how should i model it?
Should i just make it an array of Photograph?
If yes, does schema.org actually assume on ANY property that it may be multiple (amenityFeature, availableLanguage, etc. suspiciously look like that)?
Does that mean, i have to actually model every property as an array?
After some additional research i have to assume schema.org is not meant as a full data model. It is mostly about providing a common vocabulary and a hierarchy of information. Its primary use case seems to be markup, so types definitions are very vague since they have to work on content that is actually meant to be presented to a user. So i will have to specify my own schema and let my decisions and my naming be guided by schema.org.

When to maintain reference to key vs. reference to actual entity object after put operation.

When working with datastore entities in App Engine, people have noticed odd behavior after a put operation is performed on an entity if you choose to hold on to a reference of that entity.
For example, see this issue where repeated String properties mutated to _BaseValue after a put was performed.
In the ensuing discussion, in reference to a repeated String property, Guido van Rossum writes:
"I see. We should probably document that you're not supposed to hang
on to the list of items for too long; there are various forms of
undefined behavior around that."
I get the sense from this thread that it's not a good idea to maintain reference to an entity for too long after a put, as unexpected behavior might arise.
However, when I look at the GAE source code for the Model.get_or_insert() method, I see the following code (docstring removed):
#classmethod
def get_or_insert(cls, key_name, **kwds):
def txn():
entity = cls.get_by_key_name(key_name, parent=kwds.get('parent'))
if entity is None:
entity = cls(key_name=key_name, **kwds)
entity.put()
return entity
return run_in_transaction(txn)
Notice how a put operation is performed, and the entity is returned post-put. Just above, we saw an example of when this is not recommended.
Can anyone clarify when and when it is not ok to maintain a reference to an entity, post put? Guido seemed to hint that there are various scenarios when this could be a bad idea. Just curious if anyone has seen documentation on this (I cannot find any).
Thanks!
The problem described in the issue is not regarding entities, but rather lists obtained from its properties. You can hold a copy of entity as long as you like. It's just an object.
The issue is caused by some "magical" functionality provided by ndb. Let's take a look at the model definition
from google.appengine.ext.ndb import model
class MyModel(model.Model):
items = model.StringProperty(repeated=True)
What can we say about items property?
It looks like a class attribute, but metaclass logic of model.Model transforms it into an instance attribute.
What type are these instance attributes?
They can be accessed like a list of strings, but they are more complex objects having the logic required for storing and retrieving the data from datastore, validating etc.
This "magic" works well in most cases, but sometimes it doesn't. One of the problematic cases is when you get the reference to items from the instance and try to use it after put was called. Another case, mentioned by Guido, was to pass external list to initialize items property and then try to modify this property by manipulating the external list.
The thing to remember: Model properties in ndb try to behave like their basic types, but they are more complex objects. You can read more about their internals in Writing property subclasses

OOP and DB access

I used to have a single BLL class for each DataTable in my DAL.
Trying to follow OOP principles I divided each class to two classes as following:
class Item - represents a single item/row.
includes:
fields and properties according to the table's fields.
constructors - they don't access the DB
static Get method - returns a single Item from DB.
Delete method - deletes an Item from DB.
Update method - updates an Item in DB.
class Items - represents a sorted list of objects of class Item. key is the item's ID. includes:
field items_list of type SortedList
constructors - access the DB to fill items_list
GetList method - returns items_list
My questions:
1. As you can see, the Item class doesn't include any insert method, because I can't decide in which one of the classes it should be.
2. Is it ok to have a Get method in Items that will return an Item by its ID.
3. Is it ok to have Update and Delete methods in the Items class that will retrieve an Item from the items_list and then call the corresponding methods of Item.
Thank You.
You would benefit from reading about ORM and repository pattern. Once you pick a language you can use specific technologies for that, for example in C# there is NHibernate, Entity Framework, generic repository pattern are quite popular.
As you can see, the Item class doesn't include any insert method, because I can't decide in which one of the classes it should be.
Domain class shall not include any data access layer stuff. Keep it separate as these are different responsibilities. Have a look at the SOLID principles and Domain Driven Design.
Is it ok to have a Get method in Items that will return an Item by its ID.
No, not okay. Remove any data access members from the domain model classes.
Is it ok to have Update and Delete methods in the Items class that will retrieve an Item from the items_list and then call the corresponding methods of Item.
No, same reason as for the other ones.
In short, one class - one responsibility. Separate model from database interaction. Use separate generic classes to interact with the database, use ORMs. Have a look at couple of tutorials about that patterns and technologies.
Unfortunaetely the answer is 'NO' to the three question. I think that as oleksii explained in his answer, you are mixing different responsibilities in the same classes.
A class should have only one responsibility(Single Responsibility Principle).
Item should represent the data of one record so it should be limited to its properties.
Items should represent a recordset, a collection of Item (...that you might iterate). What you should get after a query, thus.
There should be at least a third class, call it DAO (Data Acess Object) or manager in charge of performing the DB operations such as Get, GetList, Update, Delete and Insert.

When should we use a DbSet with EF Code First

As the title says, when should we declare a property of type DbSet for an entity, General Guidelines ?
There are no general guidelines. Instance of DbSet<YourEntity> is your access point to loading and persisting entities of a given type. If you don't expose the property on your context type you can still create it on the fly by using dbContext.Set<YourEntity>().
The only difference between exposing and not exposing the property is in entity discovery during defining the model. When EF is first use it builds "the model" for defined entities. Entities are discovered through:
Mappings explicitly defined on DbModelBuilder instance
Configuration types explicitly registered in DbModelBuilder instance
DbSet<> properties defined in context type
Types referenced by already discovered entities
So if you don't use DbSet<> properties you must tell EF about your entities with other methods.

What does ancestor mean in the google app engine datastore

Can anyone tell or define more what is "ancestor" and give an example on it and also what it is for? I just can't grasp what it really is.
Reference: http://code.google.com/appengine/docs/python/datastore/queryclass.html#Query_ancestor
Thanks.
Transactions in GAE only exist within ancestor-descendant groups. Equivalently, quoting the docs at the URL I just gave,
All datastore operations in a
transaction must operate on entities
in the same entity group
and an "entity group", per this page in the docs, are defined by:
When the application creates an
entity, it can assign another entity
as the parent of the new entity, using
the parent argument in the Model
constructor. Assigning a parent to a
new entity puts the new entity in the
same entity group as the parent
entity.
"Ancestor" is just the transitive closure of "parent" -- i.e., given an entity, its ancestors are, its parent, its parent's parent, and so forth.

Resources