in doc-architect/doc-architect-core/src/main/java/com/docarchitect/core/scanner/impl/python/SqlAlchemyScanner.java [371:424]
private FallbackParsingStrategy<EntityResult> createFallbackStrategy() {
return (file, content) -> {
List<EntityResult> results = new ArrayList<>();
// Check if file contains SQLAlchemy patterns
if (!content.contains("class ") ||
(!content.contains("Column(") && !content.contains("mapped_column("))) {
return results;
}
// Simple regex-based extraction for basic SQLAlchemy models
Pattern classPattern = Pattern.compile("class\\s+(\\w+)\\s*\\([^)]*Base[^)]*\\):");
Matcher classMatcher = classPattern.matcher(content);
while (classMatcher.find()) {
String className = classMatcher.group(1);
// Extract table name
String tableName = className;
Matcher tablenameMatcher = TABLENAME_PATTERN.matcher(content);
if (tablenameMatcher.find()) {
tableName = tablenameMatcher.group(1);
} else {
tableName = toSnakeCase(className);
}
// Extract simple fields using regex
List<DataEntity.Field> fields = new ArrayList<>();
Pattern fieldPattern = Pattern.compile("(\\w+)\\s*=\\s*Column\\(");
Matcher fieldMatcher = fieldPattern.matcher(content);
while (fieldMatcher.find()) {
String fieldName = fieldMatcher.group(1);
if (!fieldName.startsWith("_")) {
fields.add(new DataEntity.Field(fieldName, "Unknown", true, null));
}
}
if (!fields.isEmpty()) {
DataEntity entity = new DataEntity(
className,
tableName,
TABLE_TYPE,
fields,
null,
SQLALCHEMY_MODEL_PREFIX + className
);
results.add(new EntityResult(entity, List.of()));
log.debug("Fallback parsing found entity: {} -> {}", className, tableName);
}
}
return results;
};
}