Represents a column with type information and data generation capabilities.
| 30 | |
| 31 | |
| 32 | class Column: |
| 33 | """Represents a column with type information and data generation capabilities.""" |
| 34 | |
| 35 | def __init__( |
| 36 | self, name: str, typ: str, nullable: bool, default: Any, data_shape: str | None |
| 37 | ): |
| 38 | self.name = name |
| 39 | self.typ = typ |
| 40 | self.nullable = nullable |
| 41 | self.default = default |
| 42 | self.chars = string.ascii_letters + string.digits |
| 43 | self.data_shape = data_shape |
| 44 | |
| 45 | self._years = list(range(2019, 2026)) |
| 46 | self._seq_counter = 0 |
| 47 | |
| 48 | self._hot_strings = [ |
| 49 | f"{name}_a", |
| 50 | f"{name}_b", |
| 51 | f"{name}_c", |
| 52 | "foo", |
| 53 | "bar", |
| 54 | "baz", |
| 55 | "0", |
| 56 | "1", |
| 57 | "NULL", |
| 58 | ] |
| 59 | |
| 60 | def _shaped_text(self, rng: random.Random) -> str | None: |
| 61 | """Generate text according to data_shape, or None if not applicable.""" |
| 62 | if self.data_shape == "datetime": |
| 63 | return self._random_datetime(rng) |
| 64 | elif self.data_shape == "random": |
| 65 | length = rng.randrange(5, 40) |
| 66 | return "".join(rng.choice(self.chars) for _ in range(length)) |
| 67 | elif self.data_shape == "uuid": |
| 68 | return str(uuid.UUID(int=rng.getrandbits(128), version=4)) |
| 69 | elif self.data_shape == "sequential": |
| 70 | self._seq_counter += 1 |
| 71 | return f"{self.name}_{self._seq_counter}" |
| 72 | elif self.data_shape == "zipfian": |
| 73 | rank = long_tail_rank(n=10000, a=1.3, rng=rng) |
| 74 | return f"{self.name}_{rank}" |
| 75 | elif self.data_shape is not None and self.data_shape != "duration": |
| 76 | raise ValueError(f"Unhandled data_shape {self.data_shape!r}") |
| 77 | return None |
| 78 | |
| 79 | def _shaped_float(self, rng: random.Random) -> float | None: |
| 80 | """Generate a float according to data_shape, or None if not applicable.""" |
| 81 | if self.data_shape == "duration": |
| 82 | return round(rng.uniform(10.0, 1800.0), 2) |
| 83 | return None |
| 84 | |
| 85 | def _random_date(self, rng: random.Random) -> str: |
| 86 | """Generate a uniformly random date string.""" |
| 87 | year = rng.choice(self._years) |
| 88 | return f"{year}-{rng.randrange(1, 13):02}-{rng.randrange(1, 29):02}" |
| 89 |
no outgoing calls
no test coverage detected