Skip to main content
Code Review

Return to Question

Bumped by Community user
added 5023 characters in body
Source Link

Short summary of project

Project structure:

.
│ main.py
│ README.rst
│ requirements.txt
│
├───blog
│ │ __init__.py
│ │
│ ├───domain
│ │ comment.py
│ │ post.py
│ │ __init__.py
│ │
│ ├───repository
│ │ │ __init__.py
│ │ │
│ │ ├───crud
│ │ │ base.py
│ │ │ comment.py
│ │ │ post.py
│ │ │ __init__.py
│ │ │
│ │ └───models
│ │ base.py
│ │ comment.py
│ │ post.py
│ │ __init__.py
│ │
│ └───service
│ simple.py
│ __init__.py

Business model in domain/post.py:

from dataclasses import dataclass
# from .comment import Comment
@dataclass
class Post:
 id: str
 title: str
 content: str
 # Should I implement it? If yes how to implement it here and in crud?
 # comments: list[Comment]
 #
 # def __post_init__(self):
 # if self.comments is None:
 # self.comments = []

Orm model in repository/models/post.py:

from sqlalchemy import Column, String
from sqlalchemy.orm import relationship
from .base import Base
class Post(Base):
 __tablename__ = 'posts'
 id = Column(String, primary_key=True)
 title = Column(String)
 content = Column(String)
 executions = relationship('Comment', backref='post')
 def __repr__(self):
 return f'Post(id={self.id}, title={self.title}, content={self.content})'

CRUD class to manage orm model repository/crud/post.py:

from blog.repository.crud.base import BaseRepository
from blog.repository.models.post import Post as PostModel
from blog.domain.post import Post as PostEntity
class PostRepository(BaseRepository):
 """Creates object to manage post in data in database."""
 def __init__(self, session):
 self.session = session
 def create(self, post):
 """Creates post."""
 post_model = PostModel(id=post.id, title=post.title, content=post.content)
 self.session.add(post_model)
 self.session.commit()
 def get_by_id(self, id_):
 """Gets post by id."""
 post_model = self.session.query(PostModel).get(id_)
 if post_model is not None:
 return PostEntity(id=post_model.id, title=post_model.title, content=post_model.content)

Main business logic in service/simple.py:

import time
import uuid
from blog.repository.crud.comment import CommentRepository
from blog.repository.crud.post import PostRepository
from blog.domain.post import Post
from blog.domain.comment import Comment
class SimpleService:
 """Creates simple service."""
 def __init__(self, session):
 self.session = session
 self.post_repository = PostRepository(session)
 self.comment_repository = CommentRepository(session)
 def run(self):
 """Performs fake operation (main app logic)."""
 print('Fake action in simple service...')
 print('Creating posts...')
 time.sleep(1)
 post_id = str(uuid.uuid4())
 post = Post(id=post_id,
 title='Post 1',
 content='Lorem Ipsum is simply dummy text of the printing and typesetting industry.')
 self.post_repository.create(post)
 print('Creating comment...')
 time.sleep(1)
 comment_id = str(uuid.uuid4())
 comment_1 = Comment(id=comment_id,
 content='Lorem Ipsum has been the industry\'s standard dummy text',
 post=post)
 self.comment_repository.create(comment_1)
 print('Getting post from db...')
 time.sleep(1)
 print(self.post_repository.get_by_id(post_id))
 print('Getting comment from db...')
 time.sleep(1)
 print(self.comment_repository.get_by_id(comment_id))

Entrypoint of app in main.py:

import os
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from blog.repository.models.base import Base
from blog.service.simple import SimpleService
def main():
 """Entrypoint of app."""
 database_uri = os.getenv('DATABASE_URI') # set DATABASE_URI=sqlite:///data.db
 if database_uri is None:
 database_uri = 'sqlite:///:memory:'
 engine = create_engine(database_uri)
 Base.metadata.create_all(engine)
 with Session(engine) as session:
 simple_service = SimpleService(session)
 simple_service.run()
if __name__ == '__main__':
 main()

Short summary of project

Project structure:

.
│ main.py
│ README.rst
│ requirements.txt
│
├───blog
│ │ __init__.py
│ │
│ ├───domain
│ │ comment.py
│ │ post.py
│ │ __init__.py
│ │
│ ├───repository
│ │ │ __init__.py
│ │ │
│ │ ├───crud
│ │ │ base.py
│ │ │ comment.py
│ │ │ post.py
│ │ │ __init__.py
│ │ │
│ │ └───models
│ │ base.py
│ │ comment.py
│ │ post.py
│ │ __init__.py
│ │
│ └───service
│ simple.py
│ __init__.py

Business model in domain/post.py:

from dataclasses import dataclass
# from .comment import Comment
@dataclass
class Post:
 id: str
 title: str
 content: str
 # Should I implement it? If yes how to implement it here and in crud?
 # comments: list[Comment]
 #
 # def __post_init__(self):
 # if self.comments is None:
 # self.comments = []

Orm model in repository/models/post.py:

from sqlalchemy import Column, String
from sqlalchemy.orm import relationship
from .base import Base
class Post(Base):
 __tablename__ = 'posts'
 id = Column(String, primary_key=True)
 title = Column(String)
 content = Column(String)
 executions = relationship('Comment', backref='post')
 def __repr__(self):
 return f'Post(id={self.id}, title={self.title}, content={self.content})'

CRUD class to manage orm model repository/crud/post.py:

from blog.repository.crud.base import BaseRepository
from blog.repository.models.post import Post as PostModel
from blog.domain.post import Post as PostEntity
class PostRepository(BaseRepository):
 """Creates object to manage post in data in database."""
 def __init__(self, session):
 self.session = session
 def create(self, post):
 """Creates post."""
 post_model = PostModel(id=post.id, title=post.title, content=post.content)
 self.session.add(post_model)
 self.session.commit()
 def get_by_id(self, id_):
 """Gets post by id."""
 post_model = self.session.query(PostModel).get(id_)
 if post_model is not None:
 return PostEntity(id=post_model.id, title=post_model.title, content=post_model.content)

Main business logic in service/simple.py:

import time
import uuid
from blog.repository.crud.comment import CommentRepository
from blog.repository.crud.post import PostRepository
from blog.domain.post import Post
from blog.domain.comment import Comment
class SimpleService:
 """Creates simple service."""
 def __init__(self, session):
 self.session = session
 self.post_repository = PostRepository(session)
 self.comment_repository = CommentRepository(session)
 def run(self):
 """Performs fake operation (main app logic)."""
 print('Fake action in simple service...')
 print('Creating posts...')
 time.sleep(1)
 post_id = str(uuid.uuid4())
 post = Post(id=post_id,
 title='Post 1',
 content='Lorem Ipsum is simply dummy text of the printing and typesetting industry.')
 self.post_repository.create(post)
 print('Creating comment...')
 time.sleep(1)
 comment_id = str(uuid.uuid4())
 comment_1 = Comment(id=comment_id,
 content='Lorem Ipsum has been the industry\'s standard dummy text',
 post=post)
 self.comment_repository.create(comment_1)
 print('Getting post from db...')
 time.sleep(1)
 print(self.post_repository.get_by_id(post_id))
 print('Getting comment from db...')
 time.sleep(1)
 print(self.comment_repository.get_by_id(comment_id))

Entrypoint of app in main.py:

import os
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from blog.repository.models.base import Base
from blog.service.simple import SimpleService
def main():
 """Entrypoint of app."""
 database_uri = os.getenv('DATABASE_URI') # set DATABASE_URI=sqlite:///data.db
 if database_uri is None:
 database_uri = 'sqlite:///:memory:'
 engine = create_engine(database_uri)
 Base.metadata.create_all(engine)
 with Session(engine) as session:
 simple_service = SimpleService(session)
 simple_service.run()
if __name__ == '__main__':
 main()

Few questions about Python project build in Domain Driven Design style DDD architecture pattern

Source Link

Few questions about Python project build in Domain Driven Design style

I'm trying to understand the DDD architecture pattern. I wrote a simple project in which I tried to use DDD arch. Here are my doubts after implementing it:

  1. Does it make sense to use an ORM for a DDD project? Maybe I should drop the use of Base class from declarative_base?
  2. Where should I define validators - in domain objects or in repository objects?
  3. Should SimpleService(session) take a session in the initializer or specific repositories that I will create in the main function? Now I create it here:
class SimpleService:
 """Creates simple service."""
 def __init__(self, session):
 self.session = session
 self.post_repository = PostRepository(session)
 self.comment_repository = CommentRepository(session)
  1. What should I change or improve in whole project? Please give me a quick review.
lang-py

AltStyle によって変換されたページ (->オリジナル) /