Hmm let's see we're going to - Reimplement SQLAlchemy models (we'll call it a "repository") - Reimplement SQLAlchemy sessions ("unit of work") - Add a "service layer" that doesn't even use the models -- we unroll all the model attributes into separate function parameters because that's less coupled somehow - Scatter everything across a message bus to remove any hope of debugging it - AND THIS IS JUST FOR WRITES! - Fo…
Architecture Patterns with Python
121–130 of 143 posts
Re: Architecture Patterns with Python
#122Re: Architecture Patterns with Python
#123Wow this book is a goldmine for architecture patterns. I love how easy it is to get into a topic and quickly grasp it. Having said that, from a practical and experience standpoint, using some of these patterns can really spiral out into an increased complexity and performance issues in Python, specially when you use already opinionated frameworks like Django which already uses the ActiveRecord pattern. I’ve been in c…
I think one of the biggest problems I encounter whenever I hear that a project follows strict architectural patterns essentially boils down to too many obfuscated abstractions that hide what is going on, or force you to jump through too many layers to accomplish tasks. Many files/functions/classes need to be updated to accomplish even simple tasks because somebody made a decision that you aren't allowed to do X or Y…
Re: Architecture Patterns with Python
#124Earlier quoted context omitted.
I understand not everyone agrees on what "repository" means. The session is a UoW (at two or three levels) and also a repository (in the sense of object-scoped persistence) and also like four other things. I'm sort of tolerant of bits of Session leaking into things. I'd argue that its leaking pieces are the application-level things you'd implement, not versions of them from the lower layers that you need to wrap. Whe…
You seem to have stopped reading my comment after the first sentence. I asked some specific questions about how you would do what they did if you just use SQLAlchemy as your repository/UoW.
Re: Architecture Patterns with Python
#125Earlier quoted context omitted.
The type system itself is unsound. For example, this code passes `mypy --strict`, but prints ` ` even though `bar` is annotated to return an `int`: i : int | list[int] = 0 def foo() -> None: global i i = [] def bar() -> int: if isinstance(i, int): foo() return i return 0 print(type(bar()))
So don't do this then? The type system does not have to be sound to be useful; Typescript proves this.
Don't do what?
- Don't write unsound code? There's no way to know until you run the program and find out your `int` is actually a `list`.
- Don't assume type annotations are correct? Then what's the point of all the extra code to appease the type checker if it doesn't provide any guarantees?
Re: Architecture Patterns with Python
#126Earlier quoted context omitted.
My experience is that once people have static typing to lean on they focus much less on the things that in my view are more crucial to building clean, readable code: good, consistent naming and small chunks. Just the visual clutter of adding type annotations can make the code flow less immediately clear and then due to broken windows syndrome people naturally care less and less about visual clarity.
Yeah, people from statically typed languages sometimes can't understand how dynamically typed languages can even work. How can I do anything if I don't know what type to pass?! Because we write functions like "factorial(number)" instead of "int fac(int n)".
Re: Architecture Patterns with Python
#127Earlier quoted context omitted.
Could you give me some insights what the possible alternative was that you would have rather seen? I am either now learning that the Repository pattern is something different than what I understand it to be, or there is misunderstanding here. I cannot understand how (basically) tucking away database access code in a repository can lead to complicated code, long development times, and the entire project failing.
Your understanding of the repository pattern is correct. It's the other people in this thread that seem to have misunderstood it and/or implemented it incorrectly. I use the repository pattern in virtually every service (when appropriate) and it's incredibly simple, easy to test and document, and easy to teach to coworkers. Because most of our services use the repository pattern, we can jump into any project we're no…
Re: Architecture Patterns with Python
#128Earlier quoted context omitted.
I understand that. The point is that I gain no information from it, and would need more complex typing to gain information. I keep seeing people trying to wrap their heads around various tricky covariance-vs-contravariance things (I personally can never remember which is which), or trying to make the types check for things that just seem blatantly unreasonable to me. And it takes up a lot of discussion space in my ci…
>The point is that I gain no information from it No, you do gain information from it: that the function takes an Iterable[Ducklike]. Moreover, now you can tell this just from the signature , rather than needing to discover it yourself by reading the function body (and maybe the bodies of the functions it calls, and so on ...). Being able to reason about a function without reading its implementation is a straightforwa…
I already had that information. I understand my own coding style.
>Being able to reason about a function without reading its implementation is a straightforward win.
My function bodies are generally only a few lines, but my reasoning here is based on the choice of identifier name.
Yes, it takes discipline, but it's the same kind of discipline as adding type annotations. And I find it much less obnoxious to input and read.
Re: Architecture Patterns with Python
#129Earlier quoted context omitted.
I've used SqlAlchemy in a biggish project. Had many problems, the worst ones were around session scoping and DB hitting season limits, but we had issues around the models too. The argument for hiding SqlAlchemy is nothing to do with "what if we change the DB"; that's done approximately never, and, even if so, you have some work to do, so do it at the time. YAGNI The argument is that SA models are funky things with la…
Based on that, do you find SQLModel[0] to be an elegant integration of these ideas, or a horrid ball of spaghetti? [0] https://sqlmodel.tiangolo.com/
I seem to recall using SqlModel in a pet project and having difficulty expressing many-to-many relationships, but that's buried in some branch somewhere. I recall liking the syntax more than plain SA. I suspect the benefits of SqlModel are syntactical rather than systemic?
"Spaghetti" is an unrelated problem. My problem codebase was spaghetti, and that likely increased the problem surface, but sensible code doesn't eliminate the danger
Re: Architecture Patterns with Python
#130Earlier quoted context omitted.
> I am not convinced that domain driven design works. Objects doesn't model the real world well. DDD does not necessitate OOP. You can do DDD in functional languages. I think there's a whole F# book about it. So I think you can conclude that OOP doesn't model the world well, which may or may not be true, but I think it's not valid to extend the conclusion to DDD. Is there a DDD-inherent reason why you think DDD does…
The difference is that modelling it through software gives you feedback, as you can run the software. You can't run the DDD documents.