├── models.py ├── tables.py ├── mapper.py └── main.py /models.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from datetime import datetime 3 | 4 | 5 | @dataclass 6 | class User: 7 | id: int | None 8 | username: str 9 | about: str | None 10 | 11 | 12 | @dataclass 13 | class Post: 14 | id: int 15 | text: str 16 | 17 | 18 | @dataclass 19 | class PostFull: 20 | id: int | None 21 | text: str 22 | created_at: datetime 23 | author: User 24 | -------------------------------------------------------------------------------- /tables.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import Table, Column, MetaData, Integer, String, ForeignKey 2 | 3 | metadata = MetaData() 4 | 5 | users_table = Table( 6 | 'users', 7 | metadata, 8 | Column('id', Integer, primary_key=True), 9 | Column('name', String), 10 | ) 11 | 12 | profiles_table = Table( 13 | 'profiles', 14 | metadata, 15 | Column('user_id', Integer, ForeignKey('users.id'), primary_key=True), # TODO `id` 16 | Column('about', String), 17 | ) 18 | 19 | posts_table = Table( 20 | 'posts', 21 | metadata, 22 | Column('id', Integer, primary_key=True), 23 | Column('user_id', Integer, ForeignKey('users.id')), 24 | Column('text', String), 25 | Column('date', String), 26 | ) 27 | -------------------------------------------------------------------------------- /mapper.py: -------------------------------------------------------------------------------- 1 | from sqlalchemy import select, join 2 | from sqlalchemy.orm import registry, relationship, column_property 3 | from sqlalchemy.testing.schema import mapped_column 4 | 5 | from models import User, Post, PostFull 6 | from tables import users_table, posts_table, profiles_table, metadata 7 | 8 | mapper_registry = registry(metadata=metadata) 9 | mapper_registry.map_imperatively(Post, posts_table) 10 | mapper_registry.map_imperatively( 11 | PostFull, 12 | posts_table, 13 | properties={ 14 | "user": relationship(User) 15 | } 16 | ) 17 | 18 | users_query = join(users_table, profiles_table) 19 | mapper_registry.map_imperatively( 20 | User, 21 | users_query, 22 | properties={ 23 | "username":users_table.c.name, 24 | "id":users_table.c.id, 25 | } 26 | ) 27 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from sqlalchemy import create_engine, select 4 | from sqlalchemy.orm import sessionmaker 5 | 6 | from mapper import mapper_registry 7 | from models import User, PostFull, Post 8 | 9 | 10 | def main(): 11 | engine = create_engine("sqlite:///file.db", echo=True) 12 | mapper_registry.metadata.create_all(engine) 13 | 14 | sm = sessionmaker(bind=engine) 15 | 16 | with sm() as session: 17 | user1 = User(id=None, username="hello", about="world") 18 | user2 = User(id=None, username="hello", about="world") 19 | post1 = PostFull( 20 | id=None, 21 | text="lorem ipsum", 22 | created_at=datetime.now(), 23 | author=user1, 24 | ) 25 | session.add_all([user1, user2, post1]) 26 | session.commit() 27 | 28 | with sm() as session: 29 | posts = session.execute(select(Post)).all() 30 | print(posts) 31 | 32 | 33 | if __name__ == "__main__": 34 | main() 35 | --------------------------------------------------------------------------------