Skip to content

Commit bc9a6b7

Browse files
authored
Seed Data: Fix hardcoded IDs and DB issue (#208)
* fix sequence after seed data * instead of id use name in json to identify foreign key constraints * change user id to email in api key seed * remove used id from seed.json * fix imports
1 parent 2e1adcb commit bc9a6b7

File tree

2 files changed

+100
-85
lines changed

2 files changed

+100
-85
lines changed
Lines changed: 53 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,54 @@
11
{
2-
"organization": [
3-
{
4-
"id": 1,
5-
"name": "Project Tech4dev",
6-
"is_active": true
7-
}
8-
],
9-
"projects": [
10-
{
11-
"id": 1,
12-
"name": "Glific",
13-
"description": "Two way communication platform",
14-
"is_active": true,
15-
"organization_id": 1
16-
},
17-
{
18-
"id": 2,
19-
"name": "Dalgo",
20-
"description": "Data platform for the social sector",
21-
"is_active": true,
22-
"organization_id": 1
23-
}
24-
],
25-
"users": [
26-
{
27-
"id": "4629f304-10c5-45f8-80f5-26ea1066a1cb",
28-
"email": "superuser@example.com",
29-
"password": "changethis",
30-
"full_name": "SUPERUSER",
31-
"is_active": true,
32-
"is_superuser": true
33-
},
34-
{
35-
"id": "375503ac-f9d1-465e-8a87-be6974799ce1",
36-
"email": "org_admin@example.com",
37-
"password": "admin123",
38-
"full_name": "ADMIN",
39-
"is_active": true,
40-
"is_superuser": false
41-
}
42-
],
43-
"apikeys": [
44-
{
45-
"id": 1,
46-
"organization_id": 1,
47-
"user_id": "4629f304-10c5-45f8-80f5-26ea1066a1cb",
48-
"api_key": "ApiKey No3x47A5qoIGhm0kVKjQ77dhCqEdWRIQZlEPzzzh7i8",
49-
"is_deleted": false,
50-
"deleted_at": null
51-
},
52-
{
53-
"id": 2,
54-
"organization_id": 1,
55-
"user_id": "375503ac-f9d1-465e-8a87-be6974799ce1",
56-
"api_key": "ApiKey Px8y47B6roJHin1lWLkR88eiDrFdXSJRZmFQazzai8j9",
57-
"is_deleted": false,
58-
"deleted_at": null
59-
}
60-
]
61-
}
2+
"organization": [
3+
{
4+
"name": "Project Tech4dev",
5+
"is_active": true
6+
}
7+
],
8+
"projects": [
9+
{
10+
"name": "Glific",
11+
"description": "Two way communication platform",
12+
"is_active": true,
13+
"organization_name": "Project Tech4dev"
14+
},
15+
{
16+
"name": "Dalgo",
17+
"description": "Data platform for the social sector",
18+
"is_active": true,
19+
"organization_name": "Project Tech4dev"
20+
}
21+
],
22+
"users": [
23+
{
24+
"email": "superuser@example.com",
25+
"password": "changethis",
26+
"full_name": "SUPERUSER",
27+
"is_active": true,
28+
"is_superuser": true
29+
},
30+
{
31+
"email": "org_admin@example.com",
32+
"password": "admin123",
33+
"full_name": "ADMIN",
34+
"is_active": true,
35+
"is_superuser": false
36+
}
37+
],
38+
"apikeys": [
39+
{
40+
"organization_name": "Project Tech4dev",
41+
"user_email": "superuser@example.com",
42+
"api_key": "ApiKey No3x47A5qoIGhm0kVKjQ77dhCqEdWRIQZlEPzzzh7i8",
43+
"is_deleted": false,
44+
"deleted_at": null
45+
},
46+
{
47+
"organization_name": "Project Tech4dev",
48+
"user_email": "org_admin@example.com",
49+
"api_key": "ApiKey Px8y47B6roJHin1lWLkR88eiDrFdXSJRZmFQazzai8j9",
50+
"is_deleted": false,
51+
"deleted_at": null
52+
}
53+
]
54+
}

backend/app/seed_data/seed_data.py

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
1-
import uuid
21
import json
3-
from pathlib import Path
4-
from sqlmodel import Session, select, delete
5-
from app.models import Organization, Project, User, APIKey
6-
from app.core.security import get_password_hash, encrypt_api_key
7-
from app.core.db import engine
82
import logging
93
from datetime import datetime
10-
from pydantic import BaseModel, EmailStr, UUID4, Field
11-
from typing import Optional, List
4+
from pathlib import Path
5+
from typing import Optional
6+
7+
from pydantic import BaseModel, EmailStr
8+
from sqlmodel import Session, delete, select
9+
10+
from app.core.db import engine
11+
from app.core.security import encrypt_api_key, get_password_hash
12+
from app.models import APIKey, Organization, Project, User
1213

1314

1415
# Pydantic models for data validation
1516
class OrgData(BaseModel):
16-
id: int
1717
name: str
1818
is_active: bool
1919

2020

2121
class ProjectData(BaseModel):
22-
id: int
2322
name: str
2423
description: str
2524
is_active: bool
26-
organization_id: int
25+
organization_name: str
2726

2827

2928
class UserData(BaseModel):
30-
id: str
3129
email: EmailStr
3230
full_name: str
3331
is_superuser: bool
@@ -36,9 +34,8 @@ class UserData(BaseModel):
3634

3735

3836
class APIKeyData(BaseModel):
39-
id: int
40-
organization_id: int
41-
user_id: str
37+
organization_name: str
38+
user_email: EmailStr
4239
api_key: str
4340
is_deleted: bool
4441
deleted_at: Optional[str] = None
@@ -64,10 +61,9 @@ def create_organization(session: Session, org_data_raw: dict) -> Organization:
6461
try:
6562
org_data = OrgData.model_validate(org_data_raw)
6663
logging.info(f"Creating organization: {org_data.name}")
67-
organization = Organization(
68-
id=org_data.id, name=org_data.name, is_active=org_data.is_active
69-
)
64+
organization = Organization(name=org_data.name, is_active=org_data.is_active)
7065
session.add(organization)
66+
session.flush() # Ensure ID is assigned
7167
return organization
7268
except Exception as e:
7369
logging.error(f"Error creating organization: {e}")
@@ -79,14 +75,24 @@ def create_project(session: Session, project_data_raw: dict) -> Project:
7975
try:
8076
project_data = ProjectData.model_validate(project_data_raw)
8177
logging.info(f"Creating project: {project_data.name}")
78+
# Query organization ID by name
79+
organization = session.exec(
80+
select(Organization).where(
81+
Organization.name == project_data.organization_name
82+
)
83+
).first()
84+
if not organization:
85+
raise ValueError(
86+
f"Organization '{project_data.organization_name}' not found"
87+
)
8288
project = Project(
83-
id=project_data.id,
8489
name=project_data.name,
8590
description=project_data.description,
8691
is_active=project_data.is_active,
87-
organization_id=project_data.organization_id,
92+
organization_id=organization.id,
8893
)
8994
session.add(project)
95+
session.flush() # Ensure ID is assigned
9096
return project
9197
except Exception as e:
9298
logging.error(f"Error creating project: {e}")
@@ -100,14 +106,14 @@ def create_user(session: Session, user_data_raw: dict) -> User:
100106
logging.info(f"Creating user: {user_data.email}")
101107
hashed_password = get_password_hash(user_data.password)
102108
user = User(
103-
id=uuid.UUID(user_data.id),
104109
email=user_data.email,
105110
full_name=user_data.full_name,
106111
is_superuser=user_data.is_superuser,
107112
is_active=user_data.is_active,
108113
hashed_password=hashed_password,
109114
)
110115
session.add(user)
116+
session.flush() # Ensure ID is assigned
111117
return user
112118
except Exception as e:
113119
logging.error(f"Error creating user: {e}")
@@ -118,12 +124,27 @@ def create_api_key(session: Session, api_key_data_raw: dict) -> APIKey:
118124
"""Create an API key from data."""
119125
try:
120126
api_key_data = APIKeyData.model_validate(api_key_data_raw)
121-
logging.info(f"Creating API key for user {api_key_data.user_id}")
127+
logging.info(f"Creating API key for user {api_key_data.user_email}")
128+
# Query organization ID by name
129+
organization = session.exec(
130+
select(Organization).where(
131+
Organization.name == api_key_data.organization_name
132+
)
133+
).first()
134+
if not organization:
135+
raise ValueError(
136+
f"Organization '{api_key_data.organization_name}' not found"
137+
)
138+
# Query user ID by email
139+
user = session.exec(
140+
select(User).where(User.email == api_key_data.user_email)
141+
).first()
142+
if not user:
143+
raise ValueError(f"User '{api_key_data.user_email}' not found")
122144
encrypted_api_key = encrypt_api_key(api_key_data.api_key)
123145
api_key = APIKey(
124-
id=api_key_data.id,
125-
organization_id=api_key_data.organization_id,
126-
user_id=uuid.UUID(api_key_data.user_id),
146+
organization_id=organization.id,
147+
user_id=user.id,
127148
key=encrypted_api_key,
128149
is_deleted=api_key_data.is_deleted,
129150
deleted_at=api_key_data.deleted_at,
@@ -133,6 +154,7 @@ def create_api_key(session: Session, api_key_data_raw: dict) -> APIKey:
133154
api_key_data.created_at.replace("Z", "+00:00")
134155
)
135156
session.add(api_key)
157+
session.flush() # Ensure ID is assigned
136158
return api_key
137159
except Exception as e:
138160
logging.error(f"Error creating API key: {e}")

0 commit comments

Comments
 (0)