diff options
Diffstat (limited to 'db')
| -rw-r--r-- | db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py | 56 | ||||
| -rw-r--r-- | db/models.py | 20 | ||||
| -rw-r--r-- | db/session.py | 2 |
3 files changed, 76 insertions, 2 deletions
diff --git a/db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py b/db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py new file mode 100644 index 0000000..ec5031b --- /dev/null +++ b/db/migrations/versions/202607031440-69d8b4938a12_added_more_fields_and_session.py | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | """Added more fields and session | ||
| 2 | |||
| 3 | Revision ID: 69d8b4938a12 | ||
| 4 | Revises: ac4fbf1fea31 | ||
| 5 | Create Date: 2026-07-03 14:40:55.628816 | ||
| 6 | |||
| 7 | """ | ||
| 8 | from typing import Sequence, Union | ||
| 9 | |||
| 10 | from alembic import op | ||
| 11 | import sqlalchemy as sa | ||
| 12 | import sqlmodel | ||
| 13 | |||
| 14 | |||
| 15 | # revision identifiers, used by Alembic. | ||
| 16 | revision: str = '69d8b4938a12' | ||
| 17 | down_revision: Union[str, Sequence[str], None] = 'ac4fbf1fea31' | ||
| 18 | branch_labels: Union[str, Sequence[str], None] = None | ||
| 19 | depends_on: Union[str, Sequence[str], None] = None | ||
| 20 | |||
| 21 | |||
| 22 | def upgrade() -> None: | ||
| 23 | """Upgrade schema.""" | ||
| 24 | # ### commands auto generated by Alembic - please adjust! ### | ||
| 25 | op.create_table('session', | ||
| 26 | sa.Column('id', sa.Uuid(), nullable=False), | ||
| 27 | sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()')), | ||
| 28 | sa.Column('updated', sa.DateTime(timezone=True), nullable=True), | ||
| 29 | sa.Column('user_id', sa.Uuid(), nullable=False), | ||
| 30 | sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), | ||
| 31 | sa.PrimaryKeyConstraint('id') | ||
| 32 | ) | ||
| 33 | op.add_column('authcode', sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()'))) | ||
| 34 | op.add_column('authcode', sa.Column('updated', sa.DateTime(timezone=True), nullable=True)) | ||
| 35 | op.add_column('authtoken', sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()'))) | ||
| 36 | op.add_column('authtoken', sa.Column('updated', sa.DateTime(timezone=True), nullable=True)) | ||
| 37 | op.add_column('clientapplication', sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()'))) | ||
| 38 | op.add_column('clientapplication', sa.Column('updated', sa.DateTime(timezone=True), nullable=True)) | ||
| 39 | op.add_column('user', sa.Column('created', sa.DateTime(timezone=True), nullable=False, server_default=sa.text('now()'))) | ||
| 40 | op.add_column('user', sa.Column('updated', sa.DateTime(timezone=True), nullable=True)) | ||
| 41 | # ### end Alembic commands ### | ||
| 42 | |||
| 43 | |||
| 44 | def downgrade() -> None: | ||
| 45 | """Downgrade schema.""" | ||
| 46 | # ### commands auto generated by Alembic - please adjust! ### | ||
| 47 | op.drop_column('user', 'updated') | ||
| 48 | op.drop_column('user', 'created') | ||
| 49 | op.drop_column('clientapplication', 'updated') | ||
| 50 | op.drop_column('clientapplication', 'created') | ||
| 51 | op.drop_column('authtoken', 'updated') | ||
| 52 | op.drop_column('authtoken', 'created') | ||
| 53 | op.drop_column('authcode', 'updated') | ||
| 54 | op.drop_column('authcode', 'created') | ||
| 55 | op.drop_table('session') | ||
| 56 | # ### end Alembic commands ### | ||
diff --git a/db/models.py b/db/models.py index e758671..7e0afb0 100644 --- a/db/models.py +++ b/db/models.py | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | from datetime import datetime, UTC | ||
| 1 | from uuid import uuid4, UUID, uuid7 | 2 | from uuid import uuid4, UUID, uuid7 |
| 2 | 3 | ||
| 3 | from sqlmodel import SQLModel, Field | 4 | from sqlalchemy import DateTime |
| 5 | from sqlmodel import SQLModel, Field, Relationship | ||
| 4 | from authlib.integrations.sqla_oauth2 import OAuth2ClientMixin, OAuth2AuthorizationCodeMixin, OAuth2TokenMixin | 6 | from authlib.integrations.sqla_oauth2 import OAuth2ClientMixin, OAuth2AuthorizationCodeMixin, OAuth2TokenMixin |
| 5 | 7 | ||
| 6 | from authentication.utils import bcrypt_sha256_hash | 8 | from authentication.utils import bcrypt_sha256_hash |
| @@ -8,6 +10,19 @@ from authentication.utils import bcrypt_sha256_hash | |||
| 8 | 10 | ||
| 9 | class BaseModel(SQLModel): | 11 | class BaseModel(SQLModel): |
| 10 | id: UUID | None = Field(primary_key=True, default_factory=uuid7) | 12 | id: UUID | None = Field(primary_key=True, default_factory=uuid7) |
| 13 | created: datetime = Field( | ||
| 14 | default_factory=lambda: datetime.now(tz=UTC), | ||
| 15 | sa_type=DateTime(timezone=True), | ||
| 16 | ) | ||
| 17 | updated: datetime = Field( | ||
| 18 | default=None, | ||
| 19 | nullable=True, | ||
| 20 | sa_column_kwargs={ | ||
| 21 | 'onupdate': lambda: datetime.now(tz=UTC), | ||
| 22 | }, | ||
| 23 | sa_type=DateTime(timezone=True), | ||
| 24 | ) | ||
| 25 | |||
| 11 | 26 | ||
| 12 | class User(BaseModel, table=True): | 27 | class User(BaseModel, table=True): |
| 13 | username: str = Field(unique=True, index=True) | 28 | username: str = Field(unique=True, index=True) |
| @@ -18,6 +33,9 @@ class User(BaseModel, table=True): | |||
| 18 | def set_password(self, value): | 33 | def set_password(self, value): |
| 19 | self.password = bcrypt_sha256_hash(value) | 34 | self.password = bcrypt_sha256_hash(value) |
| 20 | 35 | ||
| 36 | class Session(BaseModel, table=True): | ||
| 37 | user_id: UUID = Field(foreign_key='user.id', exclude=True) | ||
| 38 | user: User = Relationship() | ||
| 21 | 39 | ||
| 22 | class ClientApplication(BaseModel, OAuth2ClientMixin, table=True): | 40 | class ClientApplication(BaseModel, OAuth2ClientMixin, table=True): |
| 23 | name: str | 41 | name: str |
diff --git a/db/session.py b/db/session.py index ec700bd..82c0211 100644 --- a/db/session.py +++ b/db/session.py | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | from contextlib import contextmanager | 1 | from contextlib import contextmanager |
| 2 | 2 | ||
| 3 | from sqlalchemy import create_engine | ||
| 4 | from sqlalchemy.orm import sessionmaker, scoped_session | 3 | from sqlalchemy.orm import sessionmaker, scoped_session |
| 4 | from sqlmodel import create_engine | ||
| 5 | from sqlmodel import Session | 5 | from sqlmodel import Session |
| 6 | 6 | ||
| 7 | from conf import DATABASE_URL | 7 | from conf import DATABASE_URL |
