Unset values in bulk uploader in App Engine - google-app-engine

Using bulkloader in App Engine, I can get properties set to certain values or to None (or null value). I can also leave them unset if I don't include the property in bulkloader.yaml.
What I would like to do is set the property for some of the entities and leave the property unset for some other entities. Is there a way to do this?

There's no way to do this with the standard YAML configuration of the bulkloader. Note, though, that most model frameworks, including the Python one built in to App Engine, will create any missing properties when you first write a record with them, so there's not much point in going out of your way to leave them unspecified.

You can do this with a post_import_function.
Let's say you have a string property called "notes" that should be omitted if empty:
def post_process_entity(input_dict, instance, bulkload_state):
if instance['notes'] == '':
del instance['notes']
return instance

Related

Grails 3 "show" view with Fields plugin 2.1.0-SNAPSHOT

Stuck at a trivial problem in Grails 3.1.5: Show the fields of a domain object, excluding one of them, including a transient property. Yes, this is my first Grails 3 project after many years with previous versions.
The generated show.gsp contains
<f:display bean="rfaPdffile"/>
This will include a field that may contain megabytes of XML. It should never be shown interactively. The display: false constraint is no longer in the docs, and seems to be silenty ignored.
Next I tried explicitly naming the fields:
<f:with bean="rfaPdffile">
<f:display property='fileName'/>
<f:display property='pageCount'/>
...
</f:with>
This version suprisingly displays the values without any markup whatsoever. Changing display to field,
<f:with bean="rfaPdffile">
<f:field property='fileName'/>
<f:field property='pageCount'/>
...
</f:with>
sort of works, but shows editable values. So does f:all.
In addition I tried adding other attributes to f:display: properties (like in f:table), except (like in f:all). I note in passing that those two attributes have different syntax for similar purposes.
In the Field plugin docs my use case is explicitly mentioned as a design goal. I must have missed something obvious.
My aim is to quickly throw together a prototype gui, postponing the details until later. Clues are greatly appreciated
If I understood you correctly, you want to have all bean properties included in the gsp but the one with the "megabytes of XML" should not be displayed to the user?
If that is the case you can do:
f:with bean="beanName"
f:field property="firstPropertyName"
f:field property="secondPropertyName"
And the one you don't wish to display:
g:hiddenField name="propertyName" value="${beanName.propertyName?}"
f:with
So list all the properties as f:field or f:display and put the one you don't wish to display in a g:hiddenField Grails tag
You can also try:
f:field property="propertyName"
widget-hidden="true"
but the Label is not hidden in this case.
Hope it helps
My own answer: "use the force, read the source". The f:display tag has two rather obvious bugs. I will submit a pull request as soon as I can.
Bugs aside, the documentation does not mention that the plugin may pick up the "scaffold" static property from the domain, if it has one. Its value should be a map. Its "exclude" key may define a list of property names (List of String) to be excluded. This probably works already for the "f:all" tag; bug correction is needed for the "f:display" tag.
My subjective impression is that the fields plugin is in a tight spot. It is intertwined with the Grails architecture, making it sensitive to changes in Grails internals. It is also required by the standard scaffolding plugin, making it very visible. Thus it needs constant attention from maintainers, a position not to be envied. Even now conventions for default constraints seem to have changed somewhere between Grails 3.0.9 and 3.1.7.
Performance of the fields plugin is sensitive to the total number of plugins in the app where it is used. It searches all plugins dynamically for templates.
For the wish list I would prefer stricter tag naming. The main tags should be verbs. There are two main actions, show and edit. For each action there are two main variants, single bean or multiple beans.
My answer is that at present (2 March 2017) there is no answer. I have searched the Net high and low. For the index (list) and create and edit views, the fields plugin works well enough. A certain field can be easily excluded from the create and edit views, relatively easily from the list view (by listing those that should show), and in no way I could find from the show view. This is such a common need that one would suspect it will be addressed soon. Also, easily showing derived values in the show view, like 'total' for an invoice. One can do that by adding an ordered list with a list item showing the value below the generated ordered list of values, but that is kind of a hack.
In some ways, the old way was easier. Yes, it generated long views, but they were generated and didn't have to be done by the programmer - just custom touches here and there.

How to list all datasets in CKAN (not only the active ones)

I am working on a project based on CKAN, and I am required to list in a page all the datasets that have the state "active" and "draft". When you go to the datasets page, you can only see the ones that have the state marked as "active", but not "draft".
If I use the API (call the package_list() method) or REST calls (http://localhost/api/3/action/package_list), CKAN only returns "active" datasets, but not "drafts". I double and triple checked the documentation, and apparently one cannot lists the datasets by their state.
Does anybody have a clue on how to do this? Has anybody done this already?
Thanks!
If nothing else, you could write an extension to do this. The database call itself will be pretty simple:
SELECT id,title,name FROM package WHERE state='active' OR state='draft';
I managed to modify CKAN core to list the datasets that do not have the state "draft" or "deleted", and it works, but I do no want to touch CKAN's core, I want to do this using a plugin, so the normal thing to do is to implement plugins.IActions and override the package_list method with a custom one. I have already written my own extension to try to modify CKAN behavior on method package_list(), but I can't seem to figure it out how to make it work.
Here is my code:
#side_effect_free
def package_list_custom(context, data_dict=None):
datasets = []
dataset_q = (model.Session.query(model.Package)
.join(model.PackageRole))
for dataset in dataset_q:
if dataset.state != 'draft' and dataset.state != 'deleted':
datasets.append(dataset)
return [dataset.id for dataset in datasets]
class Cnaf_WorkflowPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IActions)
def get_actions(self):
return {
'package_list' : package_list_custom
}
If I modify CKAN core it works very well, but the problem is that I am not to touch it, so I am obliged to do it via an extension.
EDIT: Ok, I managed to make it work, you need to decorate the method with #side_effect_free. I modified my code, and now it works.
The package_search API is capable of this, by searching for state:draft and setting the include_drafts=True flag. Something like this:
https://my-site.com/api/action/package_search?q=state:draft&include_drafts=True
You should be able to access this from a plugin with something like: ckan.plugins.toolkit.get_action('package_search')(context=context, data_dict={'q': 'state:draft', 'include_drafts': True}) (you'll need to assemble the context yourself, containing a 'user' key for the current username and a 'userobj' key for the current user object).
Then make a page from the results.

Do not allow ".xml"/".html"/"index" in URI?

I'm going through Lift's basics in Section 3.2 SiteMap of Simply Lift and one thing struck me.
Using the default SiteMap code, you can ask for, say, info view in three ways:
GET /info,
GET /info.html,
GET /info.xml (why?).
What is more, you can request index view in four different ways:
GET /,
GET /index,
GET /index.html,
GET /index.xml.
How can I limit this behaviour to GET / for directories and GET /info for files?
P.S. All of these return 200 OK:
foursquare.com/,
foursquare.com/index,
foursquare.com/index.html,
foursquare.com/index.xml.
Shouldn't one resource have one URL only?
There are actually more than four ways that it can be parsed. The full list of known suffixes (any of which can be used to access the page) can be found here.
I think the reason for that is that lift can be used to serve any resource, so most are explicitly added by default.
I think you could disable Lift's processing of all extensions by adding this to Boot.scala:
LiftRules.explicitlyParsedSuffixes = Nil
However, I wouldn't recommend that as there may be some side-effects.
Using Req with RestHelper you can specify the suffix explicitly, but I don't know if there is such a construct to do so with Sitemap.
Actually, the code to determine whether Lift should handle the request or not is here. You can see the default extensions in the liftHandled method directly above, but they can all be overridden with LiftRules.liftRequest. Something like:
LiftRules.liftRequest append {
case r => Full(r.path.suffix.trim == "")
}
Should do the trick.
As far as why it works that way, Jason is right that Lift is designed to handle multiple types of dynamic resource.

EXT4JS Name Conventions

I'm using EXTJS 4.1 and I'm naming my components as follows. If I create a store I end it with Store and I do the same for Controllers, Models, etc. So I may have UserStore.js. I then put it in a controller. Now EXTJS will create getter and setters for it but the way it does it, is they append the name "Store" to the end so I now have the following: getUserStoreStore(). Which I don't like.
But I want to append Store to my file names so I know what files I'm working in. So for example I may have a UserModel.js, UserStore.js, UserView.js, UserController.js. If I didn't I would have 4 files Called User.js and it would be a pain to always have to remember which file I'm working in.
So my question is there a config to change the way EXTJS names these getters and setters, or do I have to live with getUserStoreStore. It gets even uglier is I have sub dir under stores so for example if I have the following:
-store
-user
-UserStore.js
-UserPersmission.js
I define the store like this:
Ext.define('MyApp.store.user.UserStore'
I then get the following setter:
getUserUserStoreStore()
Yuck! Any idea or do I just live with this?
The short answer is No
You can only change it by overriding the method that creates the 'getter', cause there is no config. Other than, f.e. .Net ExtJS uses namespaces to identify the type (f.e. the controller namespace) and not a applied suffix. In addition; other suffixes are applied by the array into which the class has been placed (f.e. store, model, view).
I recommend you to just divide by namespaces.

App Engine - why are there PhoneNumber, Link, Rating etc classes?

I haven't found any reason for the existence of a few of the App Engine classes. There's a PhoneNumber, a Link, a PostalAddress, a GeoPt, a Rating, etc. Why are these given special treatment? They don't seem to have any smarts - e.g. geo searching. I know Link has more space than a String property, but the rest?
See:
http://code.google.com/appengine/docs/java/datastore/dataclasses.html
Those types are 'semantic' types. They're present in the Java API for parity with the Python API. In the Python API, they define special behaviour with regards to the .to_xml() method - for example, a PhoneNumberProperty serializes like this:
<property name="foo" type="gd:phonenumber"><gd:phoneNumber>12345-678</gd:phoneNumber></property>
I think they're mostly just there to cover common cases and save developers time. If a lot of apps use a phone number field, why require each developer to have to write them? A developer can still write their own if they need/want to.
Not sure about java, but in python the following model/code (tested on dev server) will throw BadValueError, with the message "Invalid URL: stackoverflow.com"
class foo(db.model):
link = db.LinkProperty()
bar = foo()
bar.link = 'stackoverflow.com'
While:
bar.link = 'http://stackoverflow.com'
Works fine.
I haven't tested, but the other properties may or may not also do validation.
Basically using this types in your models allows to add indirect meta data to your code. This may be useful if you are working with any kind of universal renderer for your model classes or if you are performing validation of user input on your models.
For example if you are using PhoneNumber type for a field named userNumber you reflection based renderer may understand that it should automatically assign corresponding validator to text field which will represent it.
Regards,
Pavel.

Resources