Post by Uncle Buddy on Jun 25, 2022 21:39:35 GMT -8
Adding a place to an existing finding no longer works. The problem might be...[DELETED]
It looks like this is a good time to bring the complex places functionality up to speed with my current understanding of how a database should be structured. I recently combined findings_persons and persons_persons (two many-to-many tables) into the finding table. When I set out to do this, it also seemed like the odd table finding_places also had a one-to-one relationship with finding, so I added that too, and probably the reason that new places can no longer be added is that I didn't finish what I was doing and didn't do enough testing. That was a few months ago and I've spent enough time looking for the reason for the problem. Basically, it seems I rewrote the places functionality around that time, improving some questionable things about it, but not really finishing it.
It's true that the way finding_places was constructed did constitute a one-to-one relationship with a finding. The problem is that it should not have been constructed that way. The way it worked (which I never liked) was that the schema consisted of a primary key, a foreign key for finding_id, and foreign keys for up to nine single places, which would constitute a nested place linked to a finding. What I didn't like was that the values of the multiple nested places could be the same in many rows. As regards cardinality, this bad design did need to be moved to the finding table since a nested place would be repeated. I vaguely recall solving whatever problem this arrangement caused by putting the finding_id in the finding_places table instead of putting the finding_places_id in the finding table. This would have been correct only if the cardinality was like this: each finding can be linked to many nested places and each nested place can be linked to only one finding. Since this was wrong, the nest0 thru nest8 FKs got moved to the finding table (where they are a nuisance by the way).
As for why the places feature is broken (new places don't go into the database anymore--everything else works), I don't think that's worth worrying about. The code needs to be rewritten but first the data structure needs to be fixed. I don't care exactly what's wrong with the code if it needs to be rewritten anyway.
The easiest way to confront this is to first decide, without reference to any code or SQL, as if this was the first time I'd ever thought about it, what the cardinality of the relationships REALLY are: one-to-one, one-to-many, or many-to-many. Not what they have been thought to be in Treebard at any point in Treebard's history, but what they SHOULD be. And then rewrite the places functionality as needed to align with that reality. I don't want to oversimplify the world to fit it into Treebard. I want to figure out the world and make Treebard match that.
OK, relationship with what? Assuming that a nested_places table is needed (not finding_places like before), then it would have a primary key nested_place_id which could be used as a foreign key in another table or ignored. What would you want to link these rows with? Assertions and conclusions, obviously. Since conclusions join to form a finding (a row in the GUI's conclusions table), what first occurs to me is that the nested_place_id would be used as a foreign key to refer to a place. In the assertion table, there would be a place column and that would be the right place, and the columns in both places should be named nested_place_id.
However, where this link should take place depends not on what first occurs to me, but on the actaul cardinality of the relationships. A nested place is no longer a string composed by getting values for an ordered collection of single place ids. It's a single foreign key, it's one thing. So "Denver, Arapahoe County, Colorado" and "Denver, Denver County, Colorado" would be two separate elements even though Denver and Colorado haven't changed much; if Arapahoe County and Denver County have very different boundaries, then they have unique identities. (If it was just a matter of renaming the same county, then it would be one place with two names, but that's a different problem requiring place aliases to be worked into the data structure, which I haven't started yet, fortunately.)
So the linked pairs whose cardinality have to be determined are finding/nested_place and assertion/nested_place.
Each finding can be linked to zero or one nested_places. But each nested_place can be linked to many findings.
Each assertion can be linked to zero or one nested_place. But each nested_place can be linked to many assertions.
So it seems one of the mistakes that has made this feature so confusing is that the many side of the relationship is the nested_place, and due to the long time it took me to learn what cardinality was and how easy it is to figure it out for a relationship, I haven't done it right yet for places. I've done it every which way but right. Probably the way I'm doing it is denormalized or just plain wrong. The finding_id or the assertion_id has to go in the nested_place table. So the schema for that table will include the usual autoincrement primary key; nest0 thru nest8 which are foreign keys from the place table; a finding_id FK column and an assertion_id column. Both the latter can be null, which allows new places to be created--for example in the places tab--without linking them to anything.
While I'm restructuring the places functionality, this is the perfect time to do something else that had to be done anyway, which I was putting off since it would be an interruption of everything else. I have to move the database's place table(s) to a global database so that all the user's places become available to all the user's trees. So the user doesn't have to input the same places anew for each tree he makes.
Also I have to evaluate the usefulness of the database table places_places and whether or not it really needs to exist. It seems like double the effort (or more) to keep track of which two places can have a child-in-parent relationship when the order of the place_ids that will be stored in the new nested_place table records the same information. Possibly the very existence of the places_places table is just a throwback to the days when I thought nested places could be correctly modeled by a simple recursive place table. I would love to do away with the places_places table and the recursive Python code that I invented so that I wouldn't have to figure out how to do a many-to-many recursive query with SQL.
I suspect and/or hope that properly complex nested places (in which a place can be nested inside more than one immediate parent) can be simply modeled in a database with no recursion at all, just as data read straightforwardly out of some simple tables.
I'd already started on the assertions dialog, which was to be the climax to the first chapter of Treebard development, and it still will be, but with the places functionality in this much question, it's too early to work on it. Looks like chapter one of Treebard development will take another year. Good thing I'm not in a hurry. There are already plenty of genealogy applications available that were written in a hurry, without regard for the real relationships that the data have in the world. We don't need another app whose data structure was dumbed down so the app could be written in a hurry. Especially an app like Treebard GPS that purports to show the way for other developers of genealogy software.
It looks like this is a good time to bring the complex places functionality up to speed with my current understanding of how a database should be structured. I recently combined findings_persons and persons_persons (two many-to-many tables) into the finding table. When I set out to do this, it also seemed like the odd table finding_places also had a one-to-one relationship with finding, so I added that too, and probably the reason that new places can no longer be added is that I didn't finish what I was doing and didn't do enough testing. That was a few months ago and I've spent enough time looking for the reason for the problem. Basically, it seems I rewrote the places functionality around that time, improving some questionable things about it, but not really finishing it.
It's true that the way finding_places was constructed did constitute a one-to-one relationship with a finding. The problem is that it should not have been constructed that way. The way it worked (which I never liked) was that the schema consisted of a primary key, a foreign key for finding_id, and foreign keys for up to nine single places, which would constitute a nested place linked to a finding. What I didn't like was that the values of the multiple nested places could be the same in many rows. As regards cardinality, this bad design did need to be moved to the finding table since a nested place would be repeated. I vaguely recall solving whatever problem this arrangement caused by putting the finding_id in the finding_places table instead of putting the finding_places_id in the finding table. This would have been correct only if the cardinality was like this: each finding can be linked to many nested places and each nested place can be linked to only one finding. Since this was wrong, the nest0 thru nest8 FKs got moved to the finding table (where they are a nuisance by the way).
As for why the places feature is broken (new places don't go into the database anymore--everything else works), I don't think that's worth worrying about. The code needs to be rewritten but first the data structure needs to be fixed. I don't care exactly what's wrong with the code if it needs to be rewritten anyway.
The easiest way to confront this is to first decide, without reference to any code or SQL, as if this was the first time I'd ever thought about it, what the cardinality of the relationships REALLY are: one-to-one, one-to-many, or many-to-many. Not what they have been thought to be in Treebard at any point in Treebard's history, but what they SHOULD be. And then rewrite the places functionality as needed to align with that reality. I don't want to oversimplify the world to fit it into Treebard. I want to figure out the world and make Treebard match that.
OK, relationship with what? Assuming that a nested_places table is needed (not finding_places like before), then it would have a primary key nested_place_id which could be used as a foreign key in another table or ignored. What would you want to link these rows with? Assertions and conclusions, obviously. Since conclusions join to form a finding (a row in the GUI's conclusions table), what first occurs to me is that the nested_place_id would be used as a foreign key to refer to a place. In the assertion table, there would be a place column and that would be the right place, and the columns in both places should be named nested_place_id.
However, where this link should take place depends not on what first occurs to me, but on the actaul cardinality of the relationships. A nested place is no longer a string composed by getting values for an ordered collection of single place ids. It's a single foreign key, it's one thing. So "Denver, Arapahoe County, Colorado" and "Denver, Denver County, Colorado" would be two separate elements even though Denver and Colorado haven't changed much; if Arapahoe County and Denver County have very different boundaries, then they have unique identities. (If it was just a matter of renaming the same county, then it would be one place with two names, but that's a different problem requiring place aliases to be worked into the data structure, which I haven't started yet, fortunately.)
So the linked pairs whose cardinality have to be determined are finding/nested_place and assertion/nested_place.
Each finding can be linked to zero or one nested_places. But each nested_place can be linked to many findings.
Each assertion can be linked to zero or one nested_place. But each nested_place can be linked to many assertions.
So it seems one of the mistakes that has made this feature so confusing is that the many side of the relationship is the nested_place, and due to the long time it took me to learn what cardinality was and how easy it is to figure it out for a relationship, I haven't done it right yet for places. I've done it every which way but right. Probably the way I'm doing it is denormalized or just plain wrong. The finding_id or the assertion_id has to go in the nested_place table. So the schema for that table will include the usual autoincrement primary key; nest0 thru nest8 which are foreign keys from the place table; a finding_id FK column and an assertion_id column. Both the latter can be null, which allows new places to be created--for example in the places tab--without linking them to anything.
While I'm restructuring the places functionality, this is the perfect time to do something else that had to be done anyway, which I was putting off since it would be an interruption of everything else. I have to move the database's place table(s) to a global database so that all the user's places become available to all the user's trees. So the user doesn't have to input the same places anew for each tree he makes.
Also I have to evaluate the usefulness of the database table places_places and whether or not it really needs to exist. It seems like double the effort (or more) to keep track of which two places can have a child-in-parent relationship when the order of the place_ids that will be stored in the new nested_place table records the same information. Possibly the very existence of the places_places table is just a throwback to the days when I thought nested places could be correctly modeled by a simple recursive place table. I would love to do away with the places_places table and the recursive Python code that I invented so that I wouldn't have to figure out how to do a many-to-many recursive query with SQL.
I suspect and/or hope that properly complex nested places (in which a place can be nested inside more than one immediate parent) can be simply modeled in a database with no recursion at all, just as data read straightforwardly out of some simple tables.
I'd already started on the assertions dialog, which was to be the climax to the first chapter of Treebard development, and it still will be, but with the places functionality in this much question, it's too early to work on it. Looks like chapter one of Treebard development will take another year. Good thing I'm not in a hurry. There are already plenty of genealogy applications available that were written in a hurry, without regard for the real relationships that the data have in the world. We don't need another app whose data structure was dumbed down so the app could be written in a hurry. Especially an app like Treebard GPS that purports to show the way for other developers of genealogy software.