Data objects that reference each other - baqend

Will it cause a problem if I have objects referencing each other?
For example:
Jobs - ACL = not writeable by public
id: 10
jobname: 'Inside Sales Rep'
applicants: /db/Applicants/123456 // a refernece, not a string
Applicants - ACL = writeable by public
id: 123456
applicants: ["/db/User/1", "/db/User/2"]
job: /db/Jobs/10 // a reference, not a string
What's going on here is we have some jobs, and in a separate data class a Set that represents what users have applied for the job. As they apply, their user ID is pushed onto the Set. If they have to withdrawl, their user ID is removed from the set.
So what I'm hoping to accomplish is something like, find all jobs where user X has applied, and return those job names.
This works great, but is this going to cause some weird loop issue? I noticed when I do my query and console the result, I do get this pattern:
Jobs
Applicants
Jobs
Applicants
..... it will just keep going as long as I request it to load
Any thoughts?

Loops in references are allowed and will not cause any problems.
It's the standard behavior of the console. The attribute saves the reference to its object, and the console shows the referenced object when expanding the attribute.

Related

What's the cheapest way to store an auto increment indexed list of values in AWS?

I have a DynamoDB-based web application that uses DynamoDB to store my large JSON objects and perform simple CRUD operations on them via a web API. I would like to add a new table that acts like a categorization of these values. The user should be able to select from a selection box which category the object belongs to. If a desirable category does not exist, the user should be able to create a new category specifying a name which will be available to other objects in the future.
It is critical to the application that every one of these categories be given a integer ID that increments starting the first at 1. These numbers that are auto generated will turn into reproducible serial numbers for back end reports that will not use the user-visible text name.
So I would like to have a simple API available from the web fronted that allows me to:
A) GET /category : produces { int : string, ... } of all categories mapped to an ID
B) PUSH /category : accepts string and stores the string to the next integer
Here are some ideas for how to handle this kind of project.
Store it in DynamoDB with integer indexes. This leaves has some benefits but it leaves a lot to be desired. Firstly, there's no auto incrementing ID in DynamoDB, but I could definitely get the state of the table, create a new ID, and store the result. This might have issues with consistency and race conditions but there's probably a way to achieve this safely. It might, however, be a big anti pattern to use DynamoDB this way.
Store it in DynamoDB as one object in a table with some random index. Just store the mapping as a JSON object. This really forgets the notion of tables in DynamoDB and uses it as a simple file. It might also run into some issues with race conditions.
Use AWS ElasticCache to have a Redis key value store. This might be "the right" decision but the downside is that ElasticCache is an always on DB offering where you pay per hour. For a low-traffic web site like mine I'd be paying minumum $12/mo I think and I would really like for this to be pay per access/update due to the low volume. I'm not sure there's an auto increment feature for Redis built in the way I'd need it. But it's pretty trivial to make a trasaction that gets the length of the table, adds one, and stores a new value. Race conditions are easily avoid with this solution.
Use a SQL database like AWS Aurora or MYSQL. Well this has the same upsides as Redis, but it's also more overkill than Redis is, and also it costs a lot more and it's still always on.
Run my own in memory web service or MongoDB etc... still you're paying for constant containers running. Writing my own thing is obviously silly but I'm sure there are services that match this issue perfectly but they'd all require a constant container to run.
Is there a food way to just store a simple list, or integer mapping like this that doesn't cost a constant monthly cost? Is there a better way to do this with DynamoDB?
Store the maxCounterValue as an item in DyanamoDB.
For the PUSH /category, perform the following:
Get the current maxCounterValue.
TransactWrite:
Put the category name and id into a new item with id = maxCounterValue + 1.
Update the maxCounterValue +1, add a ConditionExpression to check that maxCounterValue = :valueFromGetOperation.
If TransactWrite fails, start at 1 again, try X more times

Query at JPA repo from list object

Need to ask query in JPA repository.
I have entity mapped like this
private String name;
private Set<String> roles;
There are two different string roles "users" and "managers"
Need to list all users and all managers respectively
tried
findAllByRolesContains(String role);
Than tried:
return userRepository.findAllByRolesContains("users");
Received response
Parameter value [%users%] did not match expected type
How should I ask it right?
tried
findAllByInRolesContains(String role);
it did not work at all
So first off, I see you didn't add the tags for "spring" and "spring data jpa" to your question. I want to remind you, that you are showing code snippets for Spring Data JPA - so a part of the Spring framework that builds upon the Java Persistence API (JPA). Make sure you understand the basics (JPA) first! Spring Data builds JPA queries under the hood and automates a lot of stuff, but it won't save you from knowing how to use JPA!
Next, if you have specific roles, i.e., not arbitrary strings ("role1324"), you might want to map an Enum instead.
But let's look at your case:
#Entity
public class User {
#Id
private String name;
#ElementCollection
private Set<String> roles;
}
So you are trying to create a query method for your repository - Spring Data generates queries based on the name of the method. The rules can be found in the reference documentation.
So what does findAllByRolesContains generate? Anything between 'find' and 'By' is just descriptive, i.e., ignored. 'Roles' is the property and 'Contains' may mean "contained in a collection" or "contained in a string".
But we are missing a level here - you want to check if a string in a collection contains something. And I have not found a way to tell Spring Data to create the correct query.
findAllByRolesLike is the closest one, but then you have to manually wrap the search string with '%'s.
Getting Spring Data to create the correct query can be fickle and if it's not straight forward, a waste of time IMHO. You can always write the query yourself:
#Query("select user from User user join user.roles role where role like %:role%")
List<User> findAllByRolesContaining(#Param("role") String role);
But if you test this with a User with roles ["admin", "administrator"], you get the same user twice?! What gives?! Well, that's just how the underlying SQL works - it filters rows and there are two rows with "username - admin" and "username - administrator".
You want the distrinct keyword to filter them out:
#Query("select distinct user from User user join user.roles role where role like %:role%")
List<User> findAllByRolesContaining(#Param("role") String role);
One more optimization: If roles is an #ElementCollection, they are fetched lazily by default. If you know that you will need to access it, you can add a join fetch user.roles before the join. This will load it eagerly. You can create 2 different methods if you like. You want to avoid fetching them if you don't need them, but if you know you'll need them, lazy loading may issue multiple queries.
The wikibook on JPA is a great resource and the book and blog of Vlad Mihalcea are the best resources on high performance JPA you can find.
Also - don't rely too much on the auto-magic of Spring Data JPA, IMHO it does more harm than good for anything but the most trivial of queries...

Autocreate new database rows

My application creates several rows of data per customer per day. Each row is modified as necessary using a form. Several modifications to a row may take place daily. At the end of the day the customer will "commit" the changes, at which point no further changes will be allowed. In each row I have a 'stage' field, stage=1 allows edits, stage=2 is committed, no further changes allows.
How can I update the stage value to 2 on commit?
In my model I have:
#property
def commit_stage(self):
self.stage = 2
self.save()
Is this the correct way to do this? And if so, how to I attach this function to a "commit" button.
I suspect you are confused about what properties do. You should absolutely not attach this sort of functionality to a property. It would be extremely surprising behaviour for something which is supposed to retrieve a value from an instance to instead modify it and save it to the db.
You can of course put this in a standard model method. But it's so trivial there is no point in doing so.
In terms of "attaching it to a button", nothing in Django can be called from the front-end without a URL and a view. You need a view that accepts the ID of the model instance from a POST request, gets the instance and modifies its stage value, then saves it. There is nothing different from the form views you already use.

How to decide dynamic work flow for a set of model?

Let consider we have 3 roles, Manager, Admin, Superadmin.
Sequence of transactions should happen like t1->t2->t3->t4.
If any employee belongs to Manager role , his transaction should happen t1->t3->t2
If any employee belongs to Admin role , his transaction should happen t1->t2->t4
If any employee belongs to Supreadmin role , his transaction should happen
t1->t2
In django how to define this dynamic workflow? So on request of employee this process should follow based on there Role.
Thank you in advance.
Generally, that sample is about non-dynamic workflow. All nodes instances counts are known at the moment of workflow definitions.
If you think about the flow from the process modeling side, visual representation and explanation to a non-technical user, the flow would be modeled as following BPMN diagram that not a far away from the textual specification:
So this directly could be translated into the viewflow class definition, where django views for the same tasks could be reused over different flow nodes, ex:
class MyFlow(Flow):
start = flow.Start(ViewT1).Next(check_role)
check_role = (
flow.Switch()
.Case(this.user_t2, cond=lambda act: act.process.created_by.role=='USER')
.Case(this.admin_t2, cond=lambda act: act.process.created_by.role=='ADMIN')
...
)
user_t2 = flow.View(ViewT2).Next(this.user_t3)
admin_t2 = flow.View(ViewT2).Next(this.admin_t4)
...
Ability to have the code that looks pretty same as the textual and visual specification the main value of the viewflow library. To do that for some cases you will need to create your own flow nodes. In the viewflow samples, you can find a dynamic split node that show how to be, if the nodes instance counts are unknown at the design time.

My test script is not finding items in dynamic web list control - list in code not updated with current info

I am having a problem in QTP with selection of a web list box and I have exhausted what I know to do to resolve it. I am hoping someone can help.
There are 5 controls in a container, 2 webedit controls and 3 weblist controls. Together, they allow entry of accounts associated with a customer, and there can be 16 accounts for any customer. There are only ever five controls active at any time, whether editing or entering information for an account. When the information for an account is entered and accepted, it changes to a read-only table row and a new set of controls appears below it for entry of the next account.
The information entered in these controls is the account number, type, description, designation, and status. The status value is contingent on the designation, and the items in the list change dynamically depending on what the user specifies for the designation. The status list is not enabled until the designation is specified.
After some experimenting with timing, I was able to get past an issue where the status list for the first account was seen by QTP as disabled even though it was clearly enabled. I was then able to advance to entry of the second account.
I change the designation on the second account and try to select an appropriate item (specified in a data table) in the status list. My specification from the data table is never found. I figured it was a problem with verbiage differences and also that I should probably anticipate that and address it now, so I wrote a function to accept three parameters, the list and up to two search items. My function searches the listbox passed to it and looks for a match (full or partial) on the search items it receives. Here is where I encountered a significant problem.
The list of the control my function received was from the previous iteration of the test, corresponding to the designation of that account. This is why my function was not finding the selection item. The list on the screen shows the appropriate items, which suggests that I am looking at the wrong object. I also get the ‘object is disabled’ message when I put my data table value directly into the list with the select statement.
The active controls are displayed below the readonly presentation of the previously entered accounts. I am very new to QTP, but I also read documentation. My only theory at this point is that ATP is not passing the right list to my function… that perhaps that how it was learned included the position, which will change each time. However, the spy identifies the screen control as the same item I processed for the preceding account, which makes my theory suspect. In addition, the other four controls, which are not dynamically changing, do not present the same problem. I can put the information in them consistently.
I apologize for the length of this question, but I wanted to be as thorough and clear as possible. Can anyone help me get past this obstacle.
There are many possiblities why it is exposing this behaviour, so let's start with something simple:
Did you try a myWebList.Refresh call before you do something with the listbox? Refresh re-identifies the object.
Have you put a break point (red dot) inside the custom function. Just see what is happening there. With the debug viewer you can enter a realtime command in the scope of that function like msgbox myWebList.exist(0) or myWebList.Highlight
Can you see how the disabled property is propagated to the webpage? If you can 'Object Spy' it as TO property, you can add it in the GUI Map description.
A more sophisticated aproach is to create a Description with the weblist properties. If you can read the disabled property as an RO property from the 'Object Spy', you can use it as an identifier like "attribute/customDisabledProperty:=false".
If you cannot correctly read the disabled property, you can create a description object and do a count on the amount of items that match that description on that page with numberOfLists = Browser("my browser").Page("my page").ChildObjects(myDescription).Count and get the last list with Set lastList = Browser("my browser").Page("my page").ChildObjects(myDescription)(numberOfLists-1)
Keep us informed. Depending on how this works out, we can work into a direction for a solution.
I figured this out early this morning. There are 4 different list boxes used, each made visible or enabled dependent on the selection of the previous list. This is why the spy found the one listed when I was using it and also why the items in the list were not appropriate to what I had selected and also why it appeared disabled to QTP but enabled to me.
I was selecting the same designation when trying to spy it. It was intuitive that the controls were all the same. I am also a windows programmer and I would have populated the same list each time with the appropriate list items, and I presumed that was what the web developer was doing. It was not and it took some time to figure that out. Now that I figured it out, everything is working fine, and I came back to report that. This was a significant, time-intensive lesson.
Thank you very much for your input. It is still useful because I am very new to QTP and every thing I learn is of value.