name: "data-model-designer" description: "Design data models for construction projects. Create entity-relationship diagrams, define schemas, and generate database structures." homepage: "https://datadrivenconstruction.io" metadata: {"openclaw": {"emoji": "📐", "os": ["darwin", "linux", "win32"], "homepage": "https://datadrivenconstruction.io", "requires": {"bins": ["python3"]}}}
Construction data management challenges: - Fragmented data across systems - Inconsistent data structures - Missing relationships between entities - Difficult data integration
Systematic data model design for construction projects, defining entities, relationships, and schemas for effective data management.
from typing import Dict, Any, List, Optional
from dataclasses import dataclass, field
from enum import Enum
import json
class DataType(Enum):
STRING = "string"
INTEGER = "integer"
FLOAT = "float"
BOOLEAN = "boolean"
DATE = "date"
DATETIME = "datetime"
TEXT = "text"
JSON = "json"
class RelationType(Enum):
ONE_TO_ONE = "1:1"
ONE_TO_MANY = "1:N"
MANY_TO_MANY = "N:M"
class ConstraintType(Enum):
PRIMARY_KEY = "primary_key"
FOREIGN_KEY = "foreign_key"
UNIQUE = "unique"
NOT_NULL = "not_null"
@dataclass
class Field:
name: str
data_type: DataType
nullable: bool = True
default: Any = None
description: str = ""
constraints: List[ConstraintType] = field(default_factory=list)
@dataclass
class Entity:
name: str
description: str
fields: List[Field] = field(default_factory=list)
primary_key: str = "id"
@dataclass
class Relationship:
name: str
from_entity: str
to_entity: str
relation_type: RelationType
from_field: str
to_field: str
class ConstructionDataModel:
"""Design data models for construction projects."""
def __init__(self, project_name: str):
self.project_name = project_name
self.entities: Dict[str, Entity] = {}
self.relationships: List[Relationship] = []
def add_entity(self, entity: Entity):
"""Add entity to model."""
self.entities[entity.name] = entity
def add_relationship(self, relationship: Relationship):
"""Add relationship between entities."""
self.relationships.append(relationship)
def create_entity(self, name: str, description: str,
fields: List[Dict[str, Any]]) -> Entity:
"""Create entity from field definitions."""
entity_fields = [
Field(
name=f['name'],
data_type=DataType(f.get('type', 'string')),
nullable=f.get('nullable', True),
default=f.get('default'),
description=f.get('description', ''),
constraints=[ConstraintType(c) for c in f.get('constraints', [])]
)
for f in fields
]
entity = Entity(name=name, description=description, fields=entity_fields)
self.add_entity(entity)
return entity
def create_relationship(self, from_entity: str, to_entity: str,
relation_type: str = "1:N",
from_field: str = None) -> Relationship:
"""Create relationship between entities."""
rel = Relationship(
name=f"{from_entity}_{to_entity}",
from_entity=from_entity,
to_entity=to_entity,
relation_type=RelationType(relation_type),
from_field=from_field or f"{to_entity.lower()}_id",
to_field="id"
)
self.add_relationship(rel)
return rel
def generate_sql_schema(self, dialect: str = "postgresql") -> str:
"""Generate SQL DDL statements."""
sql = []
type_map = {
DataType.STRING: "VARCHAR(255)",
DataType.INTEGER: "INTEGER",
DataType.FLOAT: "DECIMAL(15,2)",
DataType.BOOLEAN: "BOOLEAN",
DataType.DATE: "DATE",
DataType.DATETIME: "TIMESTAMP",
DataType.TEXT: "TEXT",
DataType.JSON: "JSONB" if dialect == "postgresql" else "JSON"
}
for name, entity in self.entities.items():
columns = []
for fld in entity.fields:
col = f" {fld.name} {type_map.get(fld.data_type, 'VARCHAR(255)')}"
if not fld.nullable:
col += " NOT NULL"
if ConstraintType.PRIMARY_KEY in fld.constraints:
col += " PRIMARY KEY"
columns.append(col)
sql.append(f"CREATE TABLE {name} (\n" + ",\n".join(columns) + "\n);")
for rel in self.relationships:
sql.append(f"""ALTER TABLE {rel.from_entity}
ADD CONSTRAINT fk_{rel.name}
FOREIGN KEY ({rel.from_field}) REFERENCES {rel.to_entity}({rel.to_field});""")
return "\n\n".join(sql)
def generate_json_schema(self) -> Dict[str, Any]:
"""Generate JSON Schema representation."""
schemas = {}
for name, entity in self.entities.items():
properties = {}
required = []
for fld in entity.fields:
prop = {"description": fld.description}
if fld.data_type == DataType.STRING:
prop["type"] = "string"
elif fld.data_type == DataType.INTEGER:
prop["type"] = "integer"
elif fld.data_type == DataType.FLOAT:
prop["type"] = "number"
elif fld.data_type == DataType.BOOLEAN:
prop["type"] = "boolean"
else:
prop["type"] = "string"
properties[fld.name] = prop
if not fld.nullable:
required.append(fld.name)
schemas[name] = {
"type": "object",
"title": entity.description,
"properties": properties,
"required": required
}
return schemas
def generate_er_diagram(self) -> str:
"""Generate Mermaid ER diagram."""
lines = ["erDiagram"]
for name, entity in self.entities.items():
for fld in entity.fields[:5]:
lines.append(f" {name} {{")
lines.append(f" {fld.data_type.value} {fld.name}")
lines.append(" }")
for rel in self.relationships:
rel_symbol = {
RelationType.ONE_TO_ONE: "||--||",
RelationType.ONE_TO_MANY: "||--o{",
RelationType.MANY_TO_MANY: "}o--o{"
}.get(rel.relation_type, "||--o{")
lines.append(f" {rel.from_entity} {rel_symbol} {rel.to_entity} : \"{rel.name}\"")
return "\n".join(lines)
def validate_model(self) -> List[str]:
"""Validate data model for issues."""
issues = []
for rel in self.relationships:
if rel.from_entity not in self.entities:
issues.append(f"Missing entity: {rel.from_entity}")
if rel.to_entity not in self.entities:
issues.append(f"Missing entity: {rel.to_entity}")
for name, entity in self.entities.items():
has_pk = any(ConstraintType.PRIMARY_KEY in f.constraints for f in entity.fields)
if not has_pk:
issues.append(f"Entity '{name}' has no primary key")
return issues
class ConstructionEntities:
"""Standard construction data entities."""
@staticmethod
def project_entity() -> Entity:
return Entity(
name="projects",
description="Construction projects",
fields=[
Field("id", DataType.INTEGER, False, constraints=[ConstraintType.PRIMARY_KEY]),
Field("code", DataType.STRING, False, constraints=[ConstraintType.UNIQUE]),
Field("name", DataType.STRING, False),
Field("status", DataType.STRING),
Field("start_date", DataType.DATE),
Field("end_date", DataType.DATE),
Field("budget", DataType.FLOAT)
]
)
@staticmethod
def activity_entity() -> Entity:
return Entity(
name="activities",
description="Schedule activities",
fields=[
Field("id", DataType.INTEGER, False, constraints=[ConstraintType.PRIMARY_KEY]),
Field("project_id", DataType.INTEGER, False),
Field("wbs_code", DataType.STRING),
Field("name", DataType.STRING, False),
Field("start_date", DataType.DATE),
Field("end_date", DataType.DATE),
Field("percent_complete", DataType.FLOAT)
]
)
@staticmethod
def cost_item_entity() -> Entity:
return Entity(
name="cost_items",
description="Project cost items",
fields=[
Field("id", DataType.INTEGER, False, constraints=[ConstraintType.PRIMARY_KEY]),
Field("project_id", DataType.INTEGER, False),
Field("wbs_code", DataType.STRING),
Field("description", DataType.STRING),
Field("budgeted_cost", DataType.FLOAT),
Field("actual_cost", DataType.FLOAT)
]
)
# Create model
model = ConstructionDataModel("Office Building A")
# Add standard entities
model.add_entity(ConstructionEntities.project_entity())
model.add_entity(ConstructionEntities.activity_entity())
model.add_entity(ConstructionEntities.cost_item_entity())
# Add relationships
model.create_relationship("activities", "projects")
model.create_relationship("cost_items", "projects")
# Generate SQL
sql = model.generate_sql_schema("postgresql")
print(sql)
model.create_entity( name="change_orders", description="Project change orders", fields=[ {"name": "id", "type": "integer", "nullable": False, "constraints": ["primary_key"]}, {"name": "project_id", "type": "integer", "nullable": False}, {"name": "amount", "type": "float"}, {"name": "status", "type": "string"} ] )訪問小蔥技能站7w4.net,解鎖更多實用的AI技能外掛。
er_diagram = model.generate_er_diagram()
print(er_diagram)
issues = model.validate_model()
for issue in issues:
print(f"Issue: {issue}")
這個Skill質量中等偏上,文件結構清晰、程式碼規範,容易上手使用。它能幫助設計建築專案的資料模型,生成資料庫結構。主要優點是功能明確、實現規範;不足之處是功能較為基礎,缺乏實際使用示例,說明文件不夠詳細,部分資訊分類可能不夠準確。對於需要基礎資料建模的使用者來說有一定幫助,但複雜場景可能不夠用。