---
title: "Seed Data Generators"
description: "Seed data generators power the Seed Service Engine by programmatically constructing typed mock values for database columns across PostgreSQL, MySQL, and SQLite. Built upon a unified class architect..."
last_updated: "2026-10-12T08:14:00.811777+00:00"
canonical_url: "https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/ecosystem-packages/seed-data-generators"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [drizzle-seed/src/services/Generators.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts)
- [drizzle-seed/src/services/SeedService.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/SeedService.ts)
- [drizzle-seed/src/services/GeneratorFuncs.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/GeneratorFuncs.ts)
- [drizzle-kit/src/introspect-pg.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/introspect-pg.ts)
- [drizzle-seed/src/index.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/index.ts)
- [drizzle-seed/src/services/versioning/v2.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts)
- [drizzle-seed/src/types/seedService.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/types/seedService.ts)
- [drizzle-seed/type-tests/pg.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/type-tests/pg.ts)
- [drizzle-seed/type-tests/sqlite.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/type-tests/sqlite.ts)
- [drizzle-seed/src/datasets/countries.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/countries.ts)
- [drizzle-seed/src/datasets/emailDomains.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/emailDomains.ts)
- [drizzle-seed/src/datasets/jobsTitles.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/jobsTitles.ts)
</details>

## Overview

Seed data generators power the [Seed Service Engine](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/ecosystem-packages/seed-service-engine) by programmatically constructing typed mock values for database columns across PostgreSQL, MySQL, and SQLite. Built upon a unified class architecture with deterministic pseudo-random number generation, these generators map database types and column constraints to realistic synthetic datasets, unique identifiers, and weighted distributions.

Sources: [drizzle-seed/src/services/Generators.ts:17-67](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L17-L67), [drizzle-seed/src/services/SeedService.ts:503-795](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/SeedService.ts#L503-L795)

## Abstract Generator Base Architecture

### Class Lifecycle and Properties

The foundational abstract class `AbstractGenerator` establishes the common contract, static metadata, and runtime properties shared by all mock data generators in `drizzle-seed`. Every concrete generator inherits static properties such as `entityKind` (defaulting to `'AbstractGenerator'`) and `version` (defaulting to `1`), alongside instance flags including `isUnique`, `notNull`, `dataType`, `timeSpent`, `arraySize`, `baseColumnDataType`, and `stringLength`.

```typescript
export abstract class AbstractGenerator<T = {}> {
	static readonly entityKind: string = 'AbstractGenerator';
	static readonly version: number = 1;

	public isUnique = false;
	public notNull = false;

	// param for generators which have a unique version of themselves
	public uniqueVersionOfGen?: new(params: T) => AbstractGenerator<T>;

	public dataType?: string;
	public timeSpent?: number;

	//
	public arraySize?: number;
	public baseColumnDataType?: string;

	// param for text-like generators
	public stringLength?: number;

	// params for GenerateValuesFromArray
	public weightedCountSeed?: number | undefined;
	public maxRepeatedValuesCount?: number | { weight: number; count: number | number[] }[] | undefined;

	public params: T;

	constructor(params?: T) {
		this.params = params === undefined ? {} as T : params as T;
	}
```
Sources: [drizzle-seed/src/services/Generators.ts:17-45](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L17-L45)

The lifecycle of a generator proceeds from instantiation through parameter initialization and value generation. When instantiated without parameters, it assigns an empty object. Subclasses implement the abstract `generate({ i }: { i: number })` method to emit typed values for individual row iterations.

```typescript
init(params: { count: number | { weight: number; count: number | number[] }[]; seed: number }): void;
init() {
	this.updateParams();
}

updateParams() {
	if ((this.params as any).arraySize !== undefined) {
		this.arraySize = (this.params as any).arraySize;
	}

	if ((this.params as any).isUnique !== undefined) {
		if ((this.params as any).isUnique === false && this.isUnique === true) {
			throw new Error('specifying non unique generator to unique column.');
		}

		this.isUnique = (this.params as any).isUnique;
	}
}

abstract generate(params: { i: number }): number | string | boolean | unknown | undefined | void;

```
Sources: [drizzle-seed/src/services/Generators.ts:47-67](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L47-L67)

### Parameter Synchronization Protocol

The `updateParams()` method normalizes configuration state by synchronizing runtime options from the parameter object onto instance properties. Specifically, it maps `arraySize` and enforces constraints on `isUnique`. If parameters specify `isUnique: false` on an instance where `isUnique` is already `true`, it throws a fatal error preventing non-unique generators from binding to unique database columns.

```typescript
updateParams() {
	if ((this.params as any).arraySize !== undefined) {
		this.arraySize = (this.params as any).arraySize;
	}

	if ((this.params as any).isUnique !== undefined) {
		if ((this.params as any).isUnique === false && this.isUnique === true) {
			throw new Error('specifying non unique generator to unique column.');
		}

		this.isUnique = (this.params as any).isUnique;
	}
}
```
Sources: [drizzle-seed/src/services/Generators.ts:52-64](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L52-L64)

> [!CAUTION]
> Attempting to pass `isUnique: false` to a generator configured for a unique column triggers an immediate `Error('specifying non unique generator to unique column.')`. Always verify column constraints before modifying generator uniqueness parameters.

In addition to parameter synchronization, `AbstractGenerator` provides structural replacement handlers for unique constraint escalation and array column wrapping. The `replaceIfUnique()` method checks for a registered `uniqueVersionOfGen` constructor and `isUnique` flag, instantiating the specialized unique variant while preserving data types and parameters. Similarly, `replaceIfArray()` detects non-array generators flagged with an `arraySize`, wrapping the base or unique generator inside a `GenerateArray` container instance.

```typescript
replaceIfUnique() {
	this.updateParams();
	if (
		this.uniqueVersionOfGen !== undefined
		&& this.isUnique === true
	) {
		const uniqueGen = new this.uniqueVersionOfGen({
			...this.params,
		});

		uniqueGen.isUnique = this.isUnique;
		uniqueGen.dataType = this.dataType;

		return uniqueGen;
	}
	return;
}

replaceIfArray() {
	this.updateParams();
	if (!(this.getEntityKind() === 'GenerateArray') && this.arraySize !== undefined) {
		const uniqueGen = this.replaceIfUnique();
		const baseColumnGen = uniqueGen === undefined ? this : uniqueGen;
		baseColumnGen.dataType = this.baseColumnDataType;
		const arrayGen = new GenerateArray(
			{
				baseColumnGen,
				size: this.arraySize,
			},
		);

		return arrayGen;
	}

	return;
}
```
Sources: [drizzle-seed/src/services/Generators.ts:73-108](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L73-L108)

### Pseudo-Random Number Generation with Pure-Rand

Generators requiring random distributions initialize stateful pseudo-random number generators (PRNGs) via the `pure-rand` library. For instance, `GenerateWeightedCount` seeds a `prand.xoroshiro128plus` instance alongside precalculated weighted index arrays, sampling uniform integer distributions across configured frequency weights during generation cycles.

```typescript
override init({ seed, count }: { count: { weight: number; count: number | number[] }[]; seed: number }) {
	const rng = prand.xoroshiro128plus(seed);
	const weightedIndices = getWeightedIndices(count.map((val) => val.weight));
	this.state = { rng, weightedIndices, weightedCount: count };
}

generate() {
	if (this.state === undefined) {
		throw new Error('state is not defined.');
	}

	// logic for this generator
	let idx: number;
	const weightedCount = this.state.weightedCount;

	[idx, this.state.rng] = prand.uniformIntDistribution(0, this.state.weightedIndices.length - 1, this.state.rng);
	const objIdx = this.state.weightedIndices[idx] as number;

	if (typeof weightedCount[objIdx]!.count === 'number') {
		return weightedCount[objIdx]!.count as number;
	} else {
		// typeof weightedCount[objIdx]!.count === 'object' // number[]
		const possCounts = weightedCount[objIdx]!.count as number[];
		[idx, this.state.rng] = prand.uniformIntDistribution(0, possCounts.length - 1, this.state.rng);
		return possCounts[idx]!;
	}
}
```
Sources: [drizzle-seed/src/services/Generators.ts:141-167](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L141-L167)

> [!NOTE]
> `drizzle-seed` relies exclusively on `prand.xoroshiro128plus` combined with explicit numeric seeds passed into generator `init` methods, guaranteeing fully reproducible test data across execution runs and database engines.

## Primitive and Temporal Generators

### Integer and Numeric Generators

The `drizzle-seed` engine handles primitive numeric types through dedicated generators designed to cover integer scalars, floating-point numbers, and coordinate systems. The `GeneratePoint` and `GenerateUniquePoint` classes instantiate underlying `GenerateNumber` and `GenerateUniqueNumber` instances with default precisions set to 10 decimal places, supporting coordinate bounds via `minXValue`, `maxXValue`, `minYValue`, and `maxYValue` parameters. Depending on the target column data type, point generators emit values as JSON objects, coordinate string tuples, or native arrays.

```typescript
export class GeneratePoint extends AbstractGenerator<{
	isUnique?: boolean;
	minXValue?: number;
	maxXValue?: number;
	minYValue?: number;
	maxYValue?: number;
	arraySize?: number;
}> {
	static override readonly entityKind: string = 'GeneratePoint';

	private state: {
		xCoordinateGen: GenerateNumber;
		yCoordinateGen: GenerateNumber;
	} | undefined;
	override uniqueVersionOfGen = GenerateUniquePoint;

	override init({ count, seed }: { count: number; seed: number }) {
		super.init({ count, seed });

		const xCoordinateGen = new GenerateNumber({
			minValue: this.params.minXValue,
			maxValue: this.params.maxXValue,
			precision: 10,
		});
		xCoordinateGen.init({ count, seed });

		const yCoordinateGen = new GenerateNumber({
			minValue: this.params.minYValue,
			maxValue: this.params.maxYValue,
			precision: 10,
		});
		yCoordinateGen.init({ count, seed });

		this.state = { xCoordinateGen, yCoordinateGen };
	}

	generate() {
		if (this.state === undefined) {
			throw new Error('state is not defined.');
		}

		const x = this.state.xCoordinateGen.generate();
		const y = this.state.yCoordinateGen.generate();

		if (this.dataType === 'json') {
			return { x, y };
		} else if (this.dataType === 'string') {
			return `[${x}, ${y}]`;
		} else {
			// if (this.dataType === "array")
			return [x, y];
		}
	}
}

export class GenerateUniquePoint extends AbstractGenerator<{
	minXValue?: number;
	maxXValue?: number;
	minYValue?: number;
	maxYValue?: number;
	isUnique?: boolean;
}> {
	static override readonly entityKind: string = 'GenerateUniquePoint';

	private state: {
		xCoordinateGen: GenerateUniqueNumber;
		yCoordinateGen: GenerateUniqueNumber;
	} | undefined;
	public override isUnique = true;

	override init({ count, seed }: { count: number; seed: number }) {
		const xCoordinateGen = new GenerateUniqueNumber({
			minValue: this.params.minXValue,
			maxValue: this.params.maxXValue,
			precision: 10,
		});
		xCoordinateGen.init({ count, seed });

		const yCoordinateGen = new GenerateUniqueNumber({
			minValue: this.params.minYValue,
```
Sources: [drizzle-seed/src/services/Generators.ts:2873-2978](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2873-L2978)

Geometric entity generation extends to linear equations via `GenerateLine`, which parameterizes linear coefficients across configurable minimum and maximum bounds for variables $A$, $B$, and $C$.

```typescript
export class GenerateLine extends AbstractGenerator<{
	isUnique?: boolean;
	minAValue?: number;
	maxAValue?: number;
	minBValue?: number;
	maxBValue?: number;
	minCValue?: number;
	maxCValue?: number;
	arraySize?: number;
}> {
	static override readonly entityKind: string = 'GenerateLine';

	private state: {
		aCoefficientGen: GenerateNumber;
		bCoefficientGen: GenerateNumber;
		cCoefficientGen: GenerateNumber;
	} | undefined;
	override uniqueVersionOfGen = GenerateUniqueLine;

```
Sources: [drizzle-seed/src/services/Generators.ts:2980-2998](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2980-L2998)

> [!NOTE]
> Point generators inspect the target column's `dataType` property at runtime, switching output formats dynamically between `{ x, y }` for JSON columns, `[x, y]` strings for string columns, and JavaScript arrays for array columns.

### Text and Paragraph Generators

Text-based primitive generation includes `GenerateLoremIpsum`, which builds multi-sentence lorem ipsum text blocks using predefined sentence datasets. The initialization phase computes the maximum possible string length based on the requested sentence count and compares it against database column length restrictions.

```typescript
export class GenerateLoremIpsum extends AbstractGenerator<{
	sentencesCount?: number;
	arraySize?: number;
}> {
	static override readonly entityKind: string = 'GenerateLoremIpsum';

	private state: {
		rng: prand.RandomGenerator;
	} | undefined;

	override init({ count, seed }: { count: number; seed: number }) {
		super.init({ count, seed });

		const rng = prand.xoroshiro128plus(seed);
		if (this.params.sentencesCount === undefined) this.params.sentencesCount = 1;

		const maxLoremIpsumSentencesLength = maxLoremIpsumLength * this.params.sentencesCount + this.params.sentencesCount
			- 1;
		if (this.stringLength !== undefined && this.stringLength < maxLoremIpsumSentencesLength) {
			throw new Error(
				`You can't use lorem ipsum generator with a db column length restriction of ${this.stringLength}. Set the maximum string length to at least ${maxLoremIpsumSentencesLength}.`,
			);
		}

		this.state = { rng };
	}
```
Sources: [drizzle-seed/src/services/Generators.ts:2768-2793](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2768-L2793)

During generation, `GenerateLoremIpsum` samples uniform integer distributions across the dataset of lorem ipsum sentences using `prand.xoroshiro128plus`, concatenating the selected sentences into the final result string.

```typescript
	generate() {
		if (this.state === undefined) {
			throw new Error('state is not defined.');
		}

		let idx, resultText: string = '';
		for (let i = 0; i < this.params.sentencesCount!; i++) {
			[idx, this.state.rng] = prand.uniformIntDistribution(0, loremIpsumSentences.length - 1, this.state.rng);
			resultText += loremIpsumSentences[idx] + ' ';
		}

		return resultText;
	}
}
```
Sources: [drizzle-seed/src/services/Generators.ts:2795-2808](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2795-L2808)

> [!CAUTION]
> If a database column enforces a maximum string length that is smaller than the minimum required size for the requested lorem ipsum sentence count, `GenerateLoremIpsum` throws an explicit error during `init()`. Always verify column length constraints when configuring paragraph generators.

## Realistic Entity Datasets

### Static Corpora and Bounded String Lengths

`drizzle-seed` incorporates static domain datasets to supply contextually accurate mock records for geographic, professional, and contact attributes. These corpora are paired with explicit string length constants to validate column schema boundaries before execution. The country dataset provides 170 recognized country names derived from census and geographical repositories, with a maximum string length boundary of 30 characters.

```typescript
export default [
	'Afghanistan',
	'Albania',
	'Algeria',
	'Angola',
	'Antigua and Barbuda',
	'Argentina',
	'Armenia',
	'Australia',
	'Austria',
	'Azerbaijan',
	'Bahamas',
	'Bahrain',
	'Bangladesh',
	'Barbados',
	'Belgium',
	'Belize',
	'Benin',
	'Bhutan',
	'Bolivia',
	'Bosnia and Herzegovina',
	'Botswana',
	'Brazil',
	'Brunei',
	'Bulgaria',
	'Burkina Faso',
	'Burundi',
	'Cambodia',
	'Cameroon',
	'Canada',
	'Cape Verde',
	'Central African Republic',
	'Chad',
	'Chile',
	'China',
	'Colombia',
	'Comoros',
	'Congo, Dem. Rep.',
	'Congo, Rep.',
	'Costa Rica',
	"Cote d'Ivoire",
	'Croatia',
	'Cyprus',
	'Czech Republic',
	'Denmark',
	'Dominican Republic',
	'Ecuador',
	'Egypt',
	'El Salvador',
	'Equatorial Guinea',
	'Eritrea',
	'Estonia',
	'Fiji',
	'Finland',
	'France',
	'Gabon',
	'Gambia',
	'Georgia',
	'Germany',
	'Ghana',
	'Greece',
	'Grenada',
	'Guatemala',
	'Guinea',
	'Guinea-Bissau',
	'Guyana',
	'Haiti',
	'Hungary',
	'Iceland',
	'India',
	'Indonesia',
	'Iran',
	'Iraq',
	'Ireland',
	'Israel',
	'Italy',
	'Jamaica',
	'Japan',
	'Jordan',
	'Kazakhstan',
```
Sources: [drizzle-seed/src/datasets/countries.ts:5-171](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/countries.ts#L5-L171), [drizzle-seed/src/datasets/countries.ts:173](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/countries.ts#L173)

Email domains comprise 23 global messaging providers and regional top-level domains, accompanied by a maximum string length constraint of 14 characters.

```typescript
export default [
	'gmail.com',
	'yahoo.com',
	'outlook.com',
	'msn.com',
	'hotmail.com',
	'aol.com',
	'hotmail.co.uk',
	'hotmail.fr',
	'yahoo.fr',
	'wanadoo.fr',
	'orange.fr',
	'comcast.net',
	'yahoo.co.uk',
	'yahoo.com.br',
	'yahoo.co.in',
	'live.com',
	'rediffmail.com',
	'free.fr',
	'gmx.de',
	'web.de',
	'ymail.com',
	'libero.it',
];
…
export const maxStringLength = 14;
```
Sources: [drizzle-seed/src/datasets/emailDomains.ts:1-24](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/emailDomains.ts#L1-L24), [drizzle-seed/src/datasets/emailDomains.ts:26](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/emailDomains.ts#L26)

Professional titles encompass 152 distinct job roles spanning engineering, management, healthcare, and administrative specializations, bounded by a maximum string length of 35 characters.

```typescript
export default [
	'Digital marketing specialist',
	'Web developer',
	'Operations manager',
	'Network engineer',
	'Event manager',
	'Software tester',
	'Teacher',
	'Ux/ui designer',
	'Wedding planner',
	'Qa analyst',
	'Litigation attorney',
	'Mechanical engineer',
	'Network administrator',
	'Account manager',
	'Brand manager',
	'Social worker',
	'Social media coordinator',
	'Email marketing specialist',
	'Hr generalist',
	'Legal assistant',
	'Nurse practitioner',
	'Account director',
	'Software engineer',
	'Purchasing agent',
	'Sales consultant',
	'Civil engineer',
	'Network security specialist',
	'Ui developer',
	'Financial planner',
	'Event planner',
	'Psychologist',
	'Electrical designer',
	'Data analyst',
	'Technical writer',
	'Tax consultant',
	'Account executive',
	'Systems administrator',
	'Database administrator',
	'Research analyst',
	'Data entry clerk',
	'Registered nurse',
	'Investment analyst',
	'Speech therapist',
	'Sales manager',
	'Landscape architect',
	'Key account manager',
	'Ux researcher',
	'Investment banker',
	'It support specialist',
	'Art director',
	'Software developer',
	'Project manager',
	'Customer service manager',
	'Procurement manager',
	'Substance abuse counselor',
	'Supply chain analyst',
	'Data engineer',
	'Accountant',
	'Sales representative',
	'Environmental consultant',
	'Electrical engineer',
	'Systems engineer',
	'Art teacher',
	'Human resources manager',
	'Inventory analyst',
	'Legal counsel',
	'Database developer',
	'Procurement specialist',
	'Systems analyst',
	'Copywriter',
	'Content writer',
	'Hr coordinator',
	'Business development manager',
	'Java developer',
	'Supply chain manager',
	'Event coordinator',
	'Family nurse practitioner',
	'Front-end engineer',
	'Customer success manager',
```
Sources: [drizzle-seed/src/datasets/jobsTitles.ts:4-152](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/jobsTitles.ts#L4-L152), [drizzle-seed/src/datasets/jobsTitles.ts:154](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/jobsTitles.ts#L154)

> [!NOTE]
> Specific geographic entries and administrative subdivisions are intentionally filtered out from standard datasets during curation to prevent inappropriate records from populating relational columns.

### Dataset Schema Summary

| Dataset Module | Sample Entries / Categories | Maximum String Length | Primary Source Reference |
| :--- | :--- | :--- | :--- |
| `countries.ts` | Afghanistan, Albania, ..., Zambia | 30 | Kaggle `countrydatacsv` |
| `emailDomains.ts` | gmail.com, yahoo.com, outlook.com, ..., libero.it | 14 | Native dataset corpus |
| `jobsTitles.ts` | Digital marketing specialist, Web developer, ..., Market analyst | 35 | Kaggle `job-description-dataset` |

Sources: [drizzle-seed/src/datasets/countries.ts:5-173](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/countries.ts#L5-L173), [drizzle-seed/src/datasets/emailDomains.ts:1-26](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/emailDomains.ts#L1-L26), [drizzle-seed/src/datasets/jobsTitles.ts:4-154](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/datasets/jobsTitles.ts#L4-L154)

## Unique Constraint Enforcement and Deduplication

### Replacement Strategies and Unique Versions

`drizzle-seed` enforces column uniqueness using replacement mechanisms and specialized generator classes designed to prevent collisions. When a base generator detects that `isUnique` is set to `true`, `replaceIfUnique()` inspects the generator's `uniqueVersionOfGen` mapping and instantiates the specialized variant with preserved parameters and data types.

```typescript
replaceIfUnique() {
	this.updateParams();
	if (
		this.uniqueVersionOfGen !== undefined
		&& this.isUnique === true
	) {
		const uniqueGen = new this.uniqueVersionOfGen({
			...this.params,
		});

		uniqueGen.isUnique = this.isUnique;
		uniqueGen.dataType = this.dataType;

		return uniqueGen;
	}
	return;
}
```
Sources: [drizzle-seed/src/services/Generators.ts:73-89](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L73-L89)

For instance, `GeneratePoint` maps its `uniqueVersionOfGen` property directly to `GenerateUniquePoint`, ensuring that coordinates are generated through dedicated unique numeric generators for each axis.

```typescript
override uniqueVersionOfGen = GenerateUniquePoint;
```
Sources: [drizzle-seed/src/services/Generators.ts:2887](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2887)

```typescript
public override isUnique = true;

override init({ count, seed }: { count: number; seed: number }) {
	const xCoordinateGen = new GenerateUniqueNumber({
		minValue: this.params.minXValue,
		maxValue: this.params.maxXValue,
		precision: 10,
	});
	xCoordinateGen.init({ count, seed });

	const yCoordinateGen = new GenerateUniqueNumber({
		minValue: this.params.minYValue,
		maxValue: this.params.maxYValue,
		precision: 10,
	});
	yCoordinateGen.init({ count, seed });

	this.state = { xCoordinateGen, yCoordinateGen };
}
```
Sources: [drizzle-seed/src/services/Generators.ts:2941-2959](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2941-L2959)

> [!WARNING]
> Specifying a non-unique generator class directly on a column marked with a unique constraint throws an immediate error during parameter updates via `updateParams()`, preventing invalid database seeding configurations before execution.

```typescript
if ((this.params as any).isUnique !== undefined) {
	if ((this.params as any).isUnique === false && this.isUnique === true) {
		throw new Error('specifying non unique generator to unique column.');
	}

	this.isUnique = (this.params as any).isUnique;
}
```
Sources: [drizzle-seed/src/services/Generators.ts:57-63](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L57-L63)

### String and Temporal Uniqueness Deduplication

String and temporal generators implement explicit boundary validations and collision-avoidance loops during initialization and record generation. `GenerateUniqueStringV2` converts the loop index `i` into a hexadecimal string (`i.toString(16)`) and pads it with randomly sampled character distributions to guarantee absolute uniqueness across requested row counts.

```typescript
generate({ i }: { i: number }) {
	if (this.state === undefined) {
		throw new Error('state is not defined.');
	}

	const minStringLength = this.state.minStringLength,
		maxStringLength = this.state.maxStringLength;
	const stringChars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
	let idx: number,
		strLength: number;
	let currStr: string;

	currStr = '';
	const uniqueStr = i.toString(16);
	[strLength, this.state.rng] = prand.uniformIntDistribution(
		minStringLength,
		maxStringLength - uniqueStr.length,
		this.state.rng,
	);
	for (let j = 0; j < strLength - uniqueStr.length; j++) {
		[idx, this.state.rng] = prand.uniformIntDistribution(
			0,
			stringChars.length - 1,
			this.state.rng,
		);
		currStr += stringChars[idx];
	}

	return uniqueStr + currStr;
}
```
Sources: [drizzle-seed/src/services/versioning/v2.ts:202-231](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L202-L231)

If the requested count exceeds the combinatorial capacity of the maximum string length, `GenerateUniqueStringV2` throws a descriptive error.

```typescript
if (maxStringLength < count.toString(16).length) {
	throw new Error(
		`You can't generate ${count} unique strings, with a maximum string length of ${maxStringLength}.`,
	);
}
```
Sources: [drizzle-seed/src/services/versioning/v2.ts:193-197](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L193-L197)

Similarly, `GenerateUniqueIntervalV2` calculates the maximum possible unique intervals using a configuration map of field boundaries spanning years down to seconds. If the requested record count exceeds this calculated ceiling, a `RangeError` is thrown.

```typescript
private config: { [key: string]: { from: number; to: number } } = {
	year: {
		from: 0,
		to: 5,
	},
	month: {
		from: 0,
		to: 11,
	},
	day: {
		from: 0,
		to: 29,
	},
	hour: {
		from: 0,
		to: 23,
	},
	minute: {
		from: 0,
		to: 59,
	},
	second: {
		from: 0,
		to: 59,
	},
};

override init({ count, seed }: { count: number; seed: number }) {
	const allFields = ['year', 'month', 'day', 'hour', 'minute', 'second'];
	let fieldsToGenerate: string[] = allFields;

	if (this.params.fields !== undefined && this.params.fields?.includes(' to ')) {
		const tokens = this.params.fields.split(' to ');
		const endIdx = allFields.indexOf(tokens[1]!);
		fieldsToGenerate = allFields.slice(0, endIdx + 1);
	} else if (this.params.fields !== undefined) {
		const endIdx = allFields.indexOf(this.params.fields);
		fieldsToGenerate = allFields.slice(0, endIdx + 1);
	}

	let maxUniqueIntervalsNumber = 1;
	for (const field of fieldsToGenerate) {
		const from = this.config[field]!.from, to = this.config[field]!.to;
		maxUniqueIntervalsNumber *= from - to + 1;
	}

	if (count > maxUniqueIntervalsNumber) {
		throw new RangeError(`count exceeds max number of unique intervals(${maxUniqueIntervalsNumber})`);
	}
```
Sources: [drizzle-seed/src/services/versioning/v2.ts:31-79](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L31-L79)

When generating records, `GenerateUniqueIntervalV2` populates an internal `Set<string>` (`intervalSet`), retrying uniform distributions until an unrecorded unique interval string is secured.

```typescript
	generate() {
		if (this.state === undefined) {
			throw new Error('state is not defined.');
		}

		let interval, numb: number;

		for (;;) {
			interval = '';

			for (const field of this.state.fieldsToGenerate) {
				const from = this.config[field]!.from, to = this.config[field]!.to;
				[numb, this.state.rng] = prand.uniformIntDistribution(from, to, this.state.rng);
				interval += `${numb} ${field} `;
			}

			if (!this.state.intervalSet.has(interval)) {
				this.state.intervalSet.add(interval);
				break;
			}
		}

		return interval;
	}
}
```
Sources: [drizzle-seed/src/services/versioning/v2.ts:86-110](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L86-L110)

> [!CAUTION]
> Relying on retry loops with `Set` collections can introduce performance bottlenecks if the requested count approaches the total combinatorial limit of the underlying configuration domain.

## Weighted Random Distributions

### Weighted Array and Count Distribution Mechanics

`drizzle-seed` implements non-uniform value selection using weighted distribution engines built on top of the `pure-rand` Xoroshiro128plus PRNG. The `GenerateWeightedCount` class manages counts associated with explicit weights, utilizing helper utilities to resolve index probabilities. During initialization, `GenerateWeightedCount` maps user-defined weights into an array of weighted indices via `getWeightedIndices`, allowing frequency-based selection during record generation.

```typescript
override init({ seed, count }: { count: { weight: number; count: number | number[] }[]; seed: number }) {
	const rng = prand.xoroshiro128plus(seed);
	const weightedIndices = getWeightedIndices(count.map((val) => val.weight));
	this.state = { rng, weightedIndices, weightedCount: count };
}
```
Sources: [drizzle-seed/src/services/Generators.ts:141-145](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L141-L145)

When `generate()` is invoked, uniform integer distribution selects an index from the precomputed weighted array. If the target count entry contains a single numeric value, it is returned directly; if the entry defines an array of possible counts, a secondary uniform distribution resolves the specific integer count to return.

```typescript
let idx: number;
const weightedCount = this.state.weightedCount;

[idx, this.state.rng] = prand.uniformIntDistribution(0, this.state.weightedIndices.length - 1, this.state.rng);
const objIdx = this.state.weightedIndices[idx] as number;

if (typeof weightedCount[objIdx]!.count === 'number') {
	return weightedCount[objIdx]!.count as number;
} else {
	// typeof weightedCount[objIdx]!.count === 'object' // number[]
	const possCounts = weightedCount[objIdx]!.count as number[];
	[idx, this.state.rng] = prand.uniformIntDistribution(0, possCounts.length - 1, this.state.rng);
	return possCounts[idx]!;
}
```
Sources: [drizzle-seed/src/services/Generators.ts:153-166](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L166-L166)

> [!NOTE]
> If `GenerateWeightedCount` is called before its `init()` lifecycle method establishes the internal state object, an explicit runtime error is thrown to prevent unseeded execution.

```typescript
if (this.state === undefined) {
	throw new Error('state is not defined.');
}
```
Sources: [drizzle-seed/src/services/Generators.ts:148-150](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L148-L150)

### WeightedRandomGenerator Configuration and Initialization

The `WeightedRandomGenerator` class distributes generation tasks across multiple wrapped sub-generators based on assigned weighting parameters. During its initialization phase, it tabulates sample frequencies across the population count to size and initialize each underlying sub-generator properly.

```typescript
override init({ count, seed }: { count: number; seed: number }) {
	const weights = this.params.map((weightedGen) => weightedGen.weight);
	const weightedIndices = getWeightedIndices(weights);

	let idx: number, valueIdx: number, tempRng = prand.xoroshiro128plus(seed);
	const indicesCounter: { [key: number]: number } = {};
	for (let i = 0; i < count; i++) {
		[idx, tempRng] = prand.uniformIntDistribution(0, weightedIndices.length - 1, tempRng);
		valueIdx = weightedIndices[idx]!;
		if (!Object.hasOwn(indicesCounter, valueIdx)) indicesCounter[valueIdx] = 0;
		indicesCounter[valueIdx]! += 1;
	}

	for (const [idx, weightedGen] of this.params.entries()) {
		weightedGen.value.isUnique = this.isUnique;
		weightedGen.value.dataType = this.dataType;
		weightedGen.value.init({ count: indicesCounter[idx]!, seed });

```
Sources: [drizzle-seed/src/services/Generators.ts:2818-2835](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2835-L2835)

| Generator Class | Entity Kind Identifier | Core State Parameters | Primary Purpose |
| :--- | :--- | :--- | :--- |
| `GenerateWeightedCount` | `GenerateWeightedCount` | `rng`, `weightedIndices`, `weightedCount` | Resolves non-uniform integer counts or ranges based on assigned weights |
| `WeightedRandomGenerator` | `WeightedRandomGenerator` | `rng`, `weightedIndices` | Routes value generation across a weighted array of sub-generators |

Sources: [drizzle-seed/src/services/Generators.ts:133-139](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L133-L139), [drizzle-seed/src/services/Generators.ts:2811-2816](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2811-L2816)

> [!TIP]
> `WeightedRandomGenerator` automatically propagates column uniqueness flags and data types down to each weighted sub-generator, instantiating unique counterpart generator classes when unique constraints are active.

```typescript
for (const [idx, weightedGen] of this.params.entries()) {
	weightedGen.value.isUnique = this.isUnique;
	weightedGen.value.dataType = this.dataType;
	weightedGen.value.init({ count: indicesCounter[idx]!, seed });

	if (
		weightedGen.value.uniqueVersionOfGen !== undefined
		&& weightedGen.value.isUnique === true
	) {
		const uniqueGen = new weightedGen.value.uniqueVersionOfGen({
			...weightedGen.value.params,
		});
		uniqueGen.init({
			count: indicesCounter[idx]!,
			seed,
		});
		uniqueGen.isUnique = weightedGen.value.isUnique;
		uniqueGen.dataType = weightedGen.value.dataType;

		weightedGen.value = uniqueGen;
	}
```
Sources: [drizzle-seed/src/services/Generators.ts:2831-2851](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L2831-L2851)

## Versioned Generator Evolutions

### Versioning Interfaces and Generator Mappings

`drizzle-seed` supports evolutionary versioning across generator implementations, allowing refined algorithms to be introduced without breaking legacy behavior. Generators declare their version via static properties on the `AbstractGenerator` base class and register variations in the global `generatorsMap` lookup structure.

```typescript
export abstract class AbstractGenerator<T = {}> {
	static readonly entityKind: string = 'AbstractGenerator';
	static readonly version: number = 1;

```
Sources: [drizzle-seed/src/services/Generators.ts:17-20](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L17-L20)

| Generator Class | Entity Kind Identifier | Version | Core State Parameters / Mappings |
| :--- | :--- | :--- | :--- |
| `GenerateInterval` | `GenerateInterval` | 1 | Standard interval generator |
| `GenerateUniqueIntervalV2` | `GenerateUniqueInterval` | 2 | `rng`, `fieldsToGenerate`, `intervalSet` |
| `GenerateString` | `GenerateString` | 1 | Standard string generator |
| `GenerateStringV2` | `GenerateString` | 2 | `rng`, `minStringLength`, `maxStringLength` |
| `GenerateUniqueStringV2` | `GenerateUniqueString` | 2 | `rng`, `minStringLength`, `maxStringLength`, `isUnique` |

Sources: [drizzle-seed/src/services/Generators.ts:816-830](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L816-L830), [drizzle-seed/src/services/versioning/v2.ts:22-29](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L22-L29), [drizzle-seed/src/services/versioning/v2.ts:116-123](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L116-L123), [drizzle-seed/src/services/versioning/v2.ts:172-179](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L172-L179)

> [!NOTE]
> The `generatorsFuncsV2` object mirrors the standard generator function bindings, providing a uniform API surface for accessing updated version behaviors during schema refinement.

```typescript
}

if (this.state!.integersCount.get(numb) === undefined || this.state!.integersCount.get(numb) === 0) {
	if (numb === currMinNumb) {
```
Sources: [drizzle-seed/src/services/Generators.ts:760-763](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/Generators.ts#L760-L763)

### GenerateStringV2 and GenerateUniqueStringV2 Execution

The `GenerateStringV2` class bounds random string lengths between 7 and 20 characters by default, adjusting parameters if a specific `stringLength` restriction is supplied. Its unique counterpart, `GenerateUniqueStringV2`, encodes the current iteration index `i` into a hexadecimal string prefix, appending randomly selected characters from a 62-character alphanumeric set (`stringChars`) to satisfy uniqueness constraints.

```typescript
override init({ seed, count }: { seed: number; count: number }) {
	const rng = prand.xoroshiro128plus(seed);

	let minStringLength = 7;
	let maxStringLength = 20;
	// TODO: revise later
	if (this.stringLength !== undefined) {
		maxStringLength = this.stringLength;
		if (maxStringLength === 1 || maxStringLength < minStringLength) minStringLength = maxStringLength;
	}

	if (maxStringLength < count.toString(16).length) {
		throw new Error(
			`You can't generate ${count} unique strings, with a maximum string length of ${maxStringLength}.`,
		);
	}

	this.state = { rng, minStringLength, maxStringLength };
}
```
Sources: [drizzle-seed/src/services/versioning/v2.ts:182-200](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L182-L200)

```typescript
generate({ i }: { i: number }) {
	if (this.state === undefined) {
		throw new Error('state is not defined.');
	}

	const minStringLength = this.state.minStringLength,
		maxStringLength = this.state.maxStringLength;
	const stringChars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
	let idx: number,
		strLength: number;
	let currStr: string;

	currStr = '';
	const uniqueStr = i.toString(16);
	[strLength, this.state.rng] = prand.uniformIntDistribution(
		minStringLength,
		maxStringLength - uniqueStr.length,
		this.state.rng,
	);
	for (let j = 0; j < strLength - uniqueStr.length; j++) {
		[idx, this.state.rng] = prand.uniformIntDistribution(
			0,
			stringChars.length - 1,
			this.state.rng,
		);
		currStr += stringChars[idx];
	}

	return uniqueStr + currStr;
}
```
Sources: [drizzle-seed/src/services/versioning/v2.ts:202-231](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L202-L231)

> [!WARNING]
> `GenerateUniqueStringV2` throws an explicit error if the requested population `count` requires more hexadecimal characters than the allowed maximum string length permits.

```typescript
if (maxStringLength < count.toString(16).length) {
	throw new Error(
		`You can't generate ${count} unique strings, with a maximum string length of ${maxStringLength}.`,
	);
}
```
Sources: [drizzle-seed/src/services/versioning/v2.ts:193-197](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-seed/src/services/versioning/v2.ts#L193-L197)

## Related

- [Seed Service Engine](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/ecosystem-packages/seed-service-engine)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/llms.txt) for all pages in this wiki.
