How to find out whether default value is used for Datastore ndb property? - python-2.7

Let's say we have a model like this:
class UserConfig(ndb.Model):
name = ndb.StringProperty()
email_subscriber = ndb.BooleanProperty(default=True)
Let's assume email_subscriber was set to default True by mistake and we want to fix that mistake and use default=False instead. I tried changing the value to default=False and that works fine for users created after that code is deployed, but that doesn't fix the problem for existing users.
Is there a way (e.g. some internal property which isn't documented in Datastore documentation), which would provide info whether given prop value was set explicitly by user or using the provided default.
I can write an upgrade which would set email_subscriber=False for all users, but I'm afraid some users might have intentionally checked this property in the app and wouldn't like to break their experience.
tl;dr: How can I determine if value in ndb object was set using the default for that property or was provided explicitly.

There is no way to know this. Once a value is set in the database there is no way to know which part of your code (ndb runs in your code from the database perspective) set the value.

Related

Attribute in OrderEntryModel coming as null even though I have defined a default value as 0.0 in items.xml

We are using hybris 6.7 version.
I have created a new attribute in AbstractOrderEntryModel and I have defined a default value for it in the items.xml as 0.00D since it is a double type.
Now when I login to the storefront and add items to cart, it is working as expected. But when I login to a user who already has an active cart to him, it throws nullpointer. I did not handle the null pointer since I have declared its default value as 0.0 and it can't be null.
Now for resolving this, is it better to handle the null pointer or to create a groovy script to update all the old and existing carts?
Thanks in advance.
Yes, you need to update old records. You can update old records with impex, groovy or db query.
Personally, I would update the existing records that have null values for the new attribute.
Handling the exception is also a possible approach, but it's slightly ugly, since you already know it's not supposed to be null.
As per good practice, we should update already existing AbstractOrderEntryModel by creating a simple data migration script via groovy, Impex, or DB query.
it's not recommended to use a null check at the code level because newly created entries will go to the model life cycle and initdefault interceptor will do the job as you have already defined the default values.

How to initialize localForage for mobile app

I'm new to mobile development and plan to build an app using plain HTML & jQuery, with Onsen UI.
I read that we can use localForage as a database and have a few questions.
Is it mandatory to have a database name for my app. If no, then other apps in mobile may also be using localForage. Will the DB be same then for all apps.
The document here says, config should be called before each action.
So, is it ok if it is initialized on page load like this:
$(document).ready(function(){
localforage.config({
name : 'myApp',
version : 1.0,
storeName : 'keyvaluepairs'
});
});
or should it be declared before each action (get, set, clear etc.)
How can we know that the action is triggering the desired database, as it is not specified in the action methods.
Is it mandatory to have a store name.
Is it mandatory to have a database name for my app. If no, then other apps in mobile may also be using localForage. Will the DB be same then for all apps.
A: Yes and no. It is in fact mandatory to have a database name. However if you leave it unset, the default value "localforage" is used.
The document here says, config should be called before each action. So, is it ok if it is initialized on page load like this ...
A: Yes, it totally fine to init in $(document).ready(cb). In fact it's fine to "initialize" at any time, as long as you make sure it happens before the first ever call to any real action (setItem/getItem, etc.).
How can we know that the action is triggering the desired database, as it is not specified in the action methods.
A: localforage can have multiple instances, whereas each instance is bound to only one database, (more precisely, it's bound to a specific store of that specific database). You know the action is targeting a specific database, because these actions are methods of a specific instance. No ambiguity here.
I personally suggest you name your instance explicitly:
var myAppDb = localforage.createInstance({
// these are the same options accepted by localforage.config()
name: 'myApp',
version : 1.0,
storeName : 'keyvaluepairs'
});
myAppDb.setItem('foo', 'bar');
This way you're 100% sure the action is fired on "myApp" database ;-)
Is it mandatory to have a store name.
Again, yes and no. But wait, hear me out, this one is a bit tricky.
Whereas the default database is actually named "localforage", store in localforage has this strange internal concept of un-named default store. I personally find it very confusing. And it behaves quite quirky when you use LOCALSTORAGE as driver.
So the rule of thumb is always name your store. Just treat it like mandatory. If you have only one store in one database, maybe name it "default". Sound better than "keyvaluepairs" don't you think?
let instance = localforage.createInstance({
driver : localforage.INDEXEDDB, // Force WebSQL; same as using setDriver()
name : name,
version : 1.0,
size : 4980736, // Size of database, in bytes. WebSQL-only for now.
storeName : 'YourStoreName', // Should be alphanumeric, with underscores.
description : 'Your Description'
});
instance.setItem("key", {"name":"abc"});
**You can set config from createInstance as well **

Django: How to depend on an externally ID, which can be switched?

Consider the following scenario:
Our Django database objects must rely on IDs that are provided by external service A (ESA) - this is because we use this ID to pull the information about objects that aren't created yet from the external directly. ESA might shut down soon, so we also pull information about the same objects from external service B (ESB), and save them as a fallback.
Because these IDs are relied on heavily in views and URLs, the ideal scenario would be to use a #property:
#property
dynamic_id = ESA_id
And then, if ESA shuts down, we can switch easily by changing dynamic_id to ESB_id. The problem with this though, is that properties cannot be used in queryset filters and various other scenarios, which is also a must in this case.
My current thought is to just save ESA_id, ESB_id, and dynamic_ID as regular fields separately and assign dynamic_ID = ESA_id, and then, in case ESA shuts down, simply go over the objects and do dynamic_ID = ESB_id.
But I feel there must be a better way?
Having ESA_id and ESB_id fields in the same table is a good solution, then you have some kind of setting (DEFAULT_SERVICE_ID='ESA_id'|'ESB_id') and your code change the lookup based on this option.
Here you can see an aproach to create filters dynamicly
https://stackoverflow.com/a/310785/1448667

Doctrine: how to set referenceOne relationship without finding() the referenced document?

we need to create a document which references one document in another collection. We know the id of the document being referenced and that's all we need to know.
our first approach is:
$referencedDocument=$repository->find($referencedId);
$newDocument->setUser($referencedDocument);
now the question is if we can do it somehow without the first line (and hitting the database). In the db (we use Mongo) reference is just an integer field and we know that target id, so finding() the $referencedDocument seems redundant.
We tried to create new User with just an id set, but that gets us an error during persisting.
Thanks!
In one of projects I used something like this:
$categoryReference = $this->getEntityManager()->getReference(ProjectCategory::class, $category['id']);
Thou, if you use Mongo, you probably need to use getDocumentManager()
So, link to doctrine docs. mongo odm 1.0.

Storing CiviCRM extension specific configuration in database

I'm building a CiviCRM extension, which would also have an admin section with UI for setting various configuration specific to the extension. I'm looking for a recommended approach for storing the configuration in the database.
One way is to create a new table in the database specifically for this purpose, but this seems like an overkill if there are only a couple of options to be saved.
Another way could be to use the civicrm_setting table, which kind of makes sense at first, but I'm not sure if this table is meant to be used for this purpose.
Any advice would be appreciated.
Yes, you can and should definitively use civicrm_setting.
civicrm_setting has a column group_name that should contain a unique identifier for your extension. I usually put the full name of the extension, like org.example.extension but it could be any string, and in core they use label name (e.g., Preference settings).
To interact with those settings, you can do the following :
// save the setting
CRM_Core_BAO_Setting::setItem($value, 'My group name', 'my_setting_name');
// get the setting
$setting = CRM_Core_BAO_Setting::getItem('My group name', 'my_setting_name');
// get all the setting for you extension
$settings = CRM_Core_BAO_Setting::getItem('My group name');
There seems to be an API for Setting but it doesn't seem to work well in CiviCRM 4.4.x. Don't know if it is better in CiviCRM 4.5.
What you could also do (our current practice) is store your configuration logic in a special class using the singleton pattern (as CiviCRM does itslef). If you want to see an example check this:
https://github.com/CiviCooP/no.maf.oppgavexml/blob/master/CRM/Oppgavexml/Config.php