New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Allow specifying Read-Only Models #125
Comments
I've been thinking exactly about the same thing just yesterday :-) There are several ways we can do that:
|
I'm leaning towards 2, as it seems logical to use views to represent read-only data. |
It's a pretty tough choice, I'll give you that. I'm prone to three, though none of the choices are flawless. One is the way Django does it, but that acts at runtime and comes with a (minor) performance penalty if you're doing if-checks for all models that come in. As for three, that one runs into naming issues. Not that this is a large problem mind you. If you were to inherit Model from ReadOnlyModel, the way the names are chosen results in slightly unexpected behaviour. That is, since "ReadOnlyModel" has the extra words "ReadOnly" bolted on top of "Model", you would expect that it inherits from Model, not the other way around. The semantics are a bit confusing. I've been playing around with the idea of maybe having a third object That's why I thought a type alias might be a solution to avoid this, but that seems to come with its own problems (I assume). The issue I see with 2 is that strictly speaking the concepts of a view and sth being read-only in SQL are not automatically linked. So normally, you can create/update/delete through a view in the underlying tables. Since views can be used that way, if you inherently combine them with "read-only", you're automatically also limiting the SQL feature set you can make available through the ORM. If you then wanted to add create/update/delete ability to views at some point in the future, you'd likely be changing your API around views. ... man, I kinda wish nim had interfaces right now. |
I totally get the naming issue, it bothers me too. And workarounds like having
This is true, but using ORM inevitably means imposing some limitation over raw SQL. That's the price you pay for convenience. Maybe, naming it
Well, we'll just have to implement delete/update/insert for View type ¯\(ツ)/¯ Doesn't seem to break anything. |
Complete agreement on my part.
But then View wouldn't be Read-Only anymore. And then either you model with the name "View" stays "Read-only" at that point and the new type would likely have a name like "CRUDView" and your then your behaviour in Views is in complete contrast to "ReadOnlyModel" to "Model". Or "View" becomes able to create/update/delete, then the new type would likely have a name like "ReadOnlyView" at which point your naming is consistent again, but your API changes and those that used View before would need to move to "ReadOnlyView" to limit their model in the same way as before. I'm personally leaning towards 3 at this point I think and just accepting the minor naming issue, which I then should likely write about in docs. But this is just my opinion and definitely not my final choice to make. |
I think I've found a great solution. We can use Check this out:
This won't compile because And this solution is cheap: just add a two-line template that does the check and use it in Sounds good? P.S. How would interfaces help in this case? |
@PhilippMDoerner pls see the linked PR for the implementation. I haven't added the tests yet but the code is already there. |
Heyho,
I use norm as an interface to an already existing database that was created by Django (I'm effectively reimplementing an already existing backend).
The way I use norm includes having multiple models on the same table, some with their FK fields resolved into the full data of those other entries, some where various fields are left out because they aren't needed.
This allows inserts with only the minimal amount of data necessary (So no entire models of linked fields necessary), while also giving me the ability to have "slices" of data from my database instead of the whole thing, avoiding unnecessary data fetches etc.
Right now, if I used one of these models and tried to instantiate an entry with it, I would run into a DbError at runtime.
It would be beneficial to move this problem to compile time by providing an alias to the
Model
type, that can do all the same things asModel
but does not have methods whose signature allow for insert/update/delete operations with them.Without the necessary procs, a developer using the library would be notified at compile time that he's doing something wrong by creating/updating/deleting with a read-only model.
I'm not sure how much effort or complexity this ads, because I'm not sure how such a model would e.g. need to handle ids.
Does this seem sensible to you as well?
If yes, are there any things are possible problems I might be overlooking?
As an example:
Let's say I have a model of a character that represents the actual table "character":
and let's say there's scenarios where I want to display just a list of characters. To save myself performance and unnecessary data fetches, I can just define an "overview" model with only the fields I would want for such a list:
Right now I could try to make a row in the table "character" with that
CharacterOverview
model. I am avoiding this right now through naming schema and documentation (well and by knowing how I intend to use them), but ideally I should never have even the possibility to make this mistake.The text was updated successfully, but these errors were encountered: