I have a User ndb.Model which has a username StringProperty that allows upper en lower case letters, at some point I wanted to fetch users by username but have the case forced to lowercase for the filtering. Therefor I added a ComputedProperty to User: username_lower which returns the lowercase version of the username as follows:
#ndb.ComputedProperty
def username_lower(self):
return self.username.lower()
then I filter the query like so:
query = query.filter(User.username_lower==username_input.lower())
This works, however it only does for users created (put) after I added this to the model. Users created before don't get filtered by this query. I first thought the ComputedProperty wasn't working for the older users. However, tried this and calling .username_lower on an old user does work.
Finally, I found a solution to this is to fetch all users and just run a .put_multi(all_users)
So seems like a ComputedProperty added later to the model works when you invoke it straight but doesn't filter at first. Does it not get indexed automatically ? or could it be a caching thing.. ?
any insight to why it was behaving like this would be welcome
thanks
this is the expected behaviour. The value of a ComputedProperty (or any property for that matter I guess) is indexed when the object is "put". The datastore does not do automatic schema updates or anything like that. When you update your schema you need to either allow for different schema versions in your code or update your entities individually. In the case of changes to indexing you have no choice but to update your entities. The MapReduce API can be used for updating entities to avoid request limitations and the like.
Related
I'm trying to build a admin app with admin-on-rest connected to Graph.cool. I's working except the relational references. On graph.cool we set up a related field to another "type" and the created fields are array of objects with a related id prop and the related type.
But admin-on-rest spect a single array of ids. I could change my schema but it will broke my database on graph.cool.
I tried some source="??" on the component but no lucky. Any ideias ? Thanks
That should be handled by the client. I'm afraid it's not implemented yet. You're welcome to give it a try if you like. Otherwise, you'll have to wait until I get some time for it
When you read in a result set in Groovy it comes in a collection of maps.
Seems like you should be able to update values inside those maps and write them back out, but I can't find anything built into groovy to allow me to do so.
I'm considering writing a routine that allows me to write a modified map by iterating over the fields of one of the result objects, taking each key/value pair and using them to create the appropriate update statement, but it could be annoying so I was wondering if anyone else had done this or if it'sa vailable already in groovy.
It seems like just a few lines of code so I'd rather not bring in hibernate for this. I'm just thinking a little "update" method that would allow:
def rows=sql.rows(query)
rows[0].name="newName"
update(sql, rows[0])
to update the first guy's name in the database. Anyone seen/created such a monster, or is something like this already built into Groovy Sql and I'm just missing it?
(I suppose you may have to point out to the update method which field is the key field, but that's doable...)
Using the rows method will actually read out all of the values into a List of GroovyRowResult so it's not really possible to update the data without creating an update method like the one you mention.
It's not really possible to do that in the generic case because your query can contain joins or a column reference that is an aggregate, etc.
If you're selecting from a single table use the Sql.eachRow method however and set the ResultSet to be an updatable one, you can use the underlying ResultSet interface to update as you iterate through:
sql.resultSetConcurrency = ResultSet.CONCUR_UPDATABLE
sql.resultSetType = ResultSet.TYPE_FORWARD_ONLY
sql.eachRow(query) { row ->
row.updateString('name', 'newName')
row.updateRow()
}
Depending on the database/driver you use, you may not be able to create an updatable ResultSet.
I have a table events, where I log different kind of events, e.g. login, register, etc. This is based on the type column.
I'd like to have different models (or any other suitable solution) for each event type, like EventLogin. Thus it would look like I have different "tables" for each event type, even though they are saved in the same table.
Edit: of course, I don't want to think about it every time, i.e. I would like to do EventLogin->where("user_id", "=", $user->id) and not have to worry about remembering to do ->where("type", "=", "login").
Is it possible?
Think this can interest you :
http://vimeo.com/53183075 (morphMany() / morphTo() usage near 7'00)
Otherwise, #TheShiftExchange is right, i up him.
Is it possible?
Yes.
Just have different model files. You'll need to set the table name, since your model name wont be the same:
protected $table = 'your_table';
Otherwise it will work as a normal table.
You can apply this same principle to forms. Rather than have one model for each table, you can instead have one model for each form - and keep all the form logic in one place.
What drawbacks can you think of if I design my REST API with query strings without parameter values? Like so:
http://host/path/to/page?edit
http://host/path/to/page?delete
http://host/path/to/page/+commentId?reply
Instead of e.g.:
http://host/api/edit?page=path/to/page
http://host/api/delete?page=path/to/page
http://host/api/reply?page=path/to/page&comment=commentId
( Edit: Any page-X?edit and page-X?delete links would trigger GET requests but wouldn't actually edit or delete the page. Instead, they show a page with a <form>, in which page-X can be edited, or a <form> with a Really delete page-X? confiramtion dialog. The actual edit/delete requests would be POST or DELETE requests. In the same manner as host/api/edit?page=path/to/page shows a page with an edit <form>. /Edit. )
Pleace note that ?action is not how query strings are usually formatted. Instead, they are usually formated like so: ?key=value;key2=v2;key3=v3
Moreover, sometimes I'd use URLs like this one:
http://host/path/to/page?delete;user=spammer
That is, I'd include a query string parameter with no value (delete) and one parameter with a value (user=spammer) (in order to delete all comments posted by the spammer)
My Web framework copes fine with query strings like ?reply. So I suppose that what I'm mostly wondering about, is can you think of any client side issues? Or any problems, should I decide to use another Web framework? (Do you know if the frameworks you use provides information on query strings without parameter values?)
(My understanding from reading http://labs.apache.org/webarch/uri/rfc/rfc3986.html is that the query string format I use is just fine, but what does that matter to all clients and server frameworks everywhere.)
(I currently use the Lift-Web framework. I've tested Play Framework too and it was possible to get hold of the value-less query strings parameters, so both Play and Lift-Web seems okay from my point of view.)
Here is a related question about query strings with no values. However, it deals with ASP.NET functions returning null in some cases: Access Query string parameters with no values in ASP.NET
Kind regards, Kaj-Magnus
Query parameters without value are no problem, but putting actions into the URI, in particular destructive ones, is.
Are you seriously thinking about "restful" design, and having a GET be a destructive action?
I need to return a constant from an HQL query in NHIbernate
SELECT new NDI.SomeQueryItem(user, account, " + someNumber + ")
FROM NDI.SomeObject object
I am trying for something like above. I've tried this:
SELECT new NDI.SomeQueryItem(user, account, :someNumber)
FROM NDI.SomeObject object
And then later:
.SetParameter("someNumber", 1).List<SomeQueryItem>();
But in the first case I get a 'Undefined alias or unknown mapping 1'. Which makes some sense since it probably thinks the 1 is an alias.
For the second I get a 'Undefined alias or unknown mapping :someNumber' which again makes some sense if it never set the parameter.
I have to believe there's some way to do this.
Please feel free to continue to believe there is some way to do this - but with HQL there isn't!
Why would you want to anyway? If you want to update the value this property to the value you specify, then do so after you've loaded the objects. Alternatively, if your result set doesn't quite match to your objects, you could alway use a SQL query (which you can still do via an NHibernate session). But the purpose of NHibernate is to map what's in your database onto objects, so specifying a manual override like this is quite rightly not allowed.
It sounds like there is a (small?) disconnect between your domain objects and your database model. What about creating a small "DTO" object to bridge this gap?
Have your query return a list of SomeQueryItemDTO (or whatever you want to call it) which, due to the naming, you know is not a true part of your domain. Then have some function to process the list and build a list of true SomeQueryItem objects by incorporating the data that is extraneous to the database.
If you're already using the Repository Pattern, this should be easier since all the ugly details are hidden inside of your repository.