diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1f578e29..ce3a1a11 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,24 +15,34 @@ jobs: steps: - name: Checkout Code uses: actions/checkout@v6 - - name: Start PostgreSQL + - name: Install prerequisites + id: install-prereqs shell: bash run: | - sudo systemctl start postgresql.service - - name: Install poetry + sudo apt install python3-poetry mssql-tools18 + background: true + - name: Start PostgreSQL shell: bash run: | - sudo apt install python3-poetry + sudo systemctl start postgresql.service + - name: Wait for poetry to be installed + wait: install-prereqs - name: Configure poetry shell: bash - run: | - python -m poetry config virtualenvs.in-project true + run: python -m poetry config virtualenvs.in-project true - name: Install dependencies + id: install-deps shell: bash if: steps.poetry-cache.outputs.cache-hit != 'true' - run: | - python -m poetry install --all-extras + run: python -m poetry install --all-extras + background: true + - name: Set up MS SQL Server + uses: hoverkraft-tech/compose-action@11beaa1c2dae4e8ed7b1665aa074723b6cecb0e4 # v3.0.0 + with: + compose-file: ./docker-compose.yml + - name: Wait for the dependencies + wait: + - install-deps - name: Run tests shell: bash - run: | - poetry run python -m unittest + run: poetry run python -m pytest -rs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 234f8fb8..0f6abfcc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,10 +41,16 @@ Please install the following software on your workstation: ## Running unit tests -Executing unit tests is straightforward: +Executing unit tests is straightforward. For example inside a Poetry shell you can run: ```bash -python -m unittest discover --verbose tests/ +pytest -rs +``` + +or outside: + +```bash +poetry run pytest -rs ``` ## Building documentation locally diff --git a/datafaker/create.py b/datafaker/create.py index 849a1ec7..ae1b5f7b 100644 --- a/datafaker/create.py +++ b/datafaker/create.py @@ -1,5 +1,4 @@ """Functions and classes to create and populate the target database.""" -import re from collections import Counter from pathlib import Path from typing import Any, Generator, Iterable, Iterator, Mapping, Sequence, Tuple @@ -8,9 +7,8 @@ import yaml from sqlalchemy import Connection, insert, inspect from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.compiler import compiles from sqlalchemy.orm import Session -from sqlalchemy.schema import CreateSchema, CreateTable, MetaData, Table +from sqlalchemy.schema import CreateSchema, MetaData, Table from datafaker.base import FileUploader from datafaker.db_utils import ( @@ -33,31 +31,6 @@ Story = Generator[Tuple[str, dict[str, Any]], dict[str, Any], None] RowCounts = Counter[str] -serial_re = re.compile(r"\bSERIAL\b") - - -@compiles(CreateTable, "duckdb") -def remove_on_delete_cascade(element: CreateTable, compiler: Any, **kw: Any) -> str: - """ - Intercede in compilation for column creation. - - DuckDB does not understand cascades, and we don't care about - that in datafaker so we remove ``ON DELETE CASCASE``. - - DuckDB does not understand ``SERIAL`` and we don't care - about autoincrementing, so we will replace it simply with - ``INTEGER``. - - Ideally ``duckdb_engine`` would remove these for us. - :param element: The CreateTable being executed. - :param compiler: Actually a DDLCompiler, but that type is not exported. - :param kw: Further arguments. - :return: Corrected SQL. - """ - text: str = compiler.visit_create_table(element, **kw) - t2 = serial_re.sub("INTEGER", text) - return t2.replace(" ON DELETE CASCADE", "") - def create_db_tables(metadata: MetaData) -> None: """Create tables described by the sqlalchemy metadata object.""" @@ -320,7 +293,7 @@ def insert(self) -> None: table = self._table_dict[self._table_name] if table.name in self._table_generator_dict: table_generator = self._table_generator_dict[table.name] - default_values = table_generator(self._dst_conn) + default_values = table_generator.generate_row(self._dst_conn) else: default_values = {} insert_values = {**default_values, **self._provided_values} @@ -403,7 +376,7 @@ def populate( with dst_conn.begin(): try: for _ in range(table_generator.num_rows_per_pass): - stmt = insert(table).values(table_generator(dst_conn)) + stmt = insert(table).values(table_generator.generate_row(dst_conn)) dst_conn.execute(stmt) row_counts[table.name] = row_counts.get(table.name, 0) + 1 dst_conn.commit() diff --git a/datafaker/db_utils.py b/datafaker/db_utils.py index 19233cca..8120d5fb 100644 --- a/datafaker/db_utils.py +++ b/datafaker/db_utils.py @@ -10,8 +10,16 @@ import sqlalchemy.dialects import yaml -# pylint: disable=no-name-in-module -from psycopg2.errors import UndefinedObject # ty: ignore[unresolved-import] +try: + # pylint: disable=no-name-in-module + from psycopg2.errors import UndefinedObject # ty: ignore[unresolved-import] +except ImportError: + # psycopg2 is only installed with the "postgres" extra; this error can + # only be raised by the psycopg2 driver, so it never matches otherwise. + class UndefinedObject: # type: ignore[no-redef] + """Placeholder when psycopg2 is not installed.""" + + from sqlalchemy import Connection, Engine, ForeignKey, create_engine, event, select from sqlalchemy.engine.interfaces import DBAPIConnection from sqlalchemy.exc import ( @@ -38,7 +46,9 @@ get_ignored_table_names, get_vocabulary_table_names, logger, + make_async_dsn, make_foreign_key_name, + unqualify_fk_target, ) # Define some types used repeatedly in the code base @@ -139,23 +149,31 @@ def create_db_engine( **kwargs: Any, ) -> MaybeAsyncEngine: """Create a SQLAlchemy Engine.""" + kwargs.setdefault("pool_pre_ping", True) try: if use_asyncio: - async_dsn = db_dsn.replace("postgresql://", "postgresql+asyncpg://") - engine: MaybeAsyncEngine = create_async_engine(async_dsn, **kwargs) + engine: MaybeAsyncEngine = create_async_engine( + make_async_dsn(db_dsn), **kwargs + ) else: engine = create_engine(db_dsn, **kwargs) except NoSuchModuleError as exc: logger.error("Failed to connect to the database: %s", exc) logger.error("Perhaps the dialect '%s' is invalid.", db_dsn.split(":")[0]) raise Exit(1) from exc + except ModuleNotFoundError as exc: + logger.error("Failed to connect to the database: %s", exc) + raise Exit(1) from exc except ValueError as exc: logger.error("DSN %s is malformed: %s", db_dsn, exc) raise Exit(1) from exc settings = {} if schema_name is not None: - settings["search_path"] = schema_name + if get_sync_engine(engine).dialect.name == "mssql": + engine = engine.execution_options(schema_translate_map={None: schema_name}) + else: + settings["search_path"] = schema_name if parquet_dir is not None: joined = ",".join(_find_parquet_directories(parquet_dir)) # double up single quotes @@ -202,11 +220,11 @@ def create_db_engine_dst( return create_db_engine(db_dsn, schema_name, use_asyncio) -def get_metadata(engine: Engine) -> MetaData: +def get_metadata(engine: Engine, schema_name: Optional[str] = None) -> MetaData: """Get the MetaData object associated with the engine passed.""" md = MetaData() try: - md.reflect(engine) + md.reflect(engine, schema=schema_name) except OperationalError as exc: logger.error("Cannot connect to database: %s", exc) raise Exit(1) from exc @@ -417,10 +435,13 @@ def reinstate_vocab_foreign_key_constraints( ].items(): fk_targets = column_dict.get("foreign_keys", []) if fk_targets: + table_names = frozenset(meta_dict.get("tables", {}).keys()) fk = ForeignKeyConstraint( columns=[column_name], name=make_foreign_key_name(vocab_table_name, column_name), - refcolumns=fk_targets, + refcolumns=[ + unqualify_fk_target(t, table_names) for t in fk_targets + ], ) logger.debug("Restoring foreign key constraint %s", fk.name) with Session(dst_engine) as session: diff --git a/datafaker/dialects.py b/datafaker/dialects.py new file mode 100644 index 00000000..b966255f --- /dev/null +++ b/datafaker/dialects.py @@ -0,0 +1,328 @@ +"""Dialect differences.""" +import re +from collections.abc import Mapping +from typing import Any, Optional, TypeVar + +from sqlalchemy import Column, Select, Table +from sqlalchemy.ext.compiler import compiles +from sqlalchemy.schema import CreateSchema, CreateTable +from sqlalchemy.sql.elements import ColumnElement +from sqlalchemy.sql.selectable import NamedFromClause +from sqlalchemy.sql.visitors import ( + ExternallyTraversible, + InternalTraversal, + replacement_traverse, + traverse, +) +from sqlalchemy.types import Date, DateTime + +T = TypeVar("T") + +serial_re = re.compile(r"\bSERIAL\b") + + +class TableReplacer: + """ + Replaces tables with aliased tables. + + We need this to work around a DuckDB problem: + If we are using the ORM code to select a column ``c`` from a table + ``t.parquet``, then DuckDB expects the SQL + ``SELECT "t.parquet".c FROM "t.parquet"`` if ``t.parquet`` is an actual + table in the database, or ``SELECT t.c FROM "t.parquet"`` if ``t.parquet`` + names a file. The best way around this seems to be to use an aliased table, + which works in both cases: ``SELECT a.c FROM "t.parquet" AS a``, and the + best way for that to happen seems to be to use ``replacement_traverse``. + """ + + def __init__(self, table: Table) -> None: + """Initialise with the table to be aliased.""" + self.table = table + self.atable = self.table.alias(f"_{table.name}__alias") + + def replace( + self, obj: ExternallyTraversible, **_kw: Any + ) -> ExternallyTraversible | None: + """Replace columns with the same column on the aliased table.""" + if isinstance(obj, Column): + if obj.table == self.table: + return self.atable.columns[obj.name] + elif isinstance(obj, Table) and obj == self.table: + return self.atable + elif isinstance(obj, NamedFromClause): + # Return the same object rather than None + # to supress descent into this object + return obj + return None + + def aliased_table(self) -> NamedFromClause: + """Get the aliased table.""" + return self.atable + + +@compiles(Select, "duckdb") +def duckdb_workaround(element: Select, compiler: Any, **kw: Any) -> Any: + """ + Transform a SQLAlchemy ORM statement to work around DuckDB issues. + + :param stmt: An ORM statement, such as the return value of ``select``. + :return: An ORM statement, transformed if necessary. + """ + tables: set[Table] = set() + traverse(element, {}, {"table": tables.add}) + for t in tables: + tr = TableReplacer(t) + opts: Mapping[str, Any] = {} + element = replacement_traverse(element, opts, tr.replace) # type: ignore + return compiler.visit_select(element, **kw) + + +@compiles(CreateTable, "mssql") +def compile_mssql_create_table(element: CreateTable, compiler: Any, **kw: Any) -> str: + """ + Post-process MS-SQL CREATE TABLE DDL. + + 1. Strip ON DELETE CASCADE — MS-SQL rejects multiple cascading FK paths to + the same table (error 1785). Referential integrity is enforced by insert + order in datafaker, so CASCADE is not needed. + 2. Strip IDENTITY — datafaker generates PK values explicitly via + ColumnValueProvider.increment(), so auto-generation is not needed and + would cause INSERT to fail without SET IDENTITY_INSERT ON. + """ + text: str = compiler.visit_create_table(element, **kw) + text = text.replace(" ON DELETE CASCADE", "") + text = re.sub(r"\s+IDENTITY(\(\d+,\s*\d+\))?", "", text) + return text + + +@compiles(CreateSchema, "mssql") +def mssql_create_schema(element: CreateSchema, _compiler: Any, **_kw: Any) -> str: + """Correct CREATE SCHEMA IF NOT EXISTS.""" + name = element.element.replace("'", "''") + if element.if_not_exists: + return ( + "IF NOT EXISTS (SELECT 1 FROM sys.schemas" + f" WHERE name = '{name}')" + f" BEGIN EXEC('CREATE SCHEMA {name}') END" + ) + return f"CREATE SCHEMA {name}" + + +@compiles(CreateTable, "duckdb") +def remove_on_delete_cascade(element: CreateTable, compiler: Any, **kw: Any) -> str: + """ + Intercede in compilation for column creation. + + DuckDB does not understand cascades, and we don't care about + that in datafaker so we remove ``ON DELETE CASCASE``. + + DuckDB does not understand ``SERIAL`` and we don't care + about autoincrementing, so we will replace it simply with + ``INTEGER``. + + Ideally ``duckdb_engine`` would remove these for us. + :param element: The CreateTable being executed. + :param compiler: Actually a DDLCompiler, but that type is not exported. + :param kw: Further arguments. + :return: Corrected SQL. + """ + text: str = compiler.visit_create_table(element, **kw) + t2 = serial_re.sub("INTEGER", text) + return t2.replace(" ON DELETE CASCADE", "") + + +class SecondsDifference(ColumnElement[int]): # pylint: disable=too-many-ancestors + """Represent getting the difference between times in seconds.""" + + expr1: ColumnElement[Date | DateTime] + expr2: ColumnElement[Date | DateTime] + + _traverse_internals = [ + ("expr1", InternalTraversal.dp_clauseelement), + ("expr2", InternalTraversal.dp_clauseelement), + ] + + def __init__( + self, + expr1: ColumnElement[Date | DateTime], + expr2: ColumnElement[Date | DateTime], + ): + """ + Get a clause for the number of seconds between two times. + + The interval is from ``expr2`` to ``expr1``. + """ + self.expr1 = expr1 + self.expr2 = expr2 + + __sa_operate__ = ColumnElement.operate + + +@compiles(SecondsDifference) +def compile_seconds_difference( + element: SecondsDifference, compiler: Any, **kw: Any +) -> str: + """Create SQL for the difference between two datetimes in seconds.""" + e1 = compiler.process(element.expr1, **kw) + e2 = compiler.process(element.expr2, **kw) + return f"CAST(EXTRACT(EPOCH FROM ({e1})) - EXTRACT(EPOCH FROM ({e2})) AS FLOAT)" + + +@compiles(SecondsDifference, "mssql") +def compile_seconds_difference_mssql( + element: SecondsDifference, compiler: Any, **kw: Any +) -> str: + """MSSQL equivalent: EXTRACT(EPOCH FROM …) is not available; use DATEDIFF.""" + e1 = compiler.process(element.expr1, **kw) + e2 = compiler.process(element.expr2, **kw) + return f"CAST(DATEDIFF(second, {e2}, {e1}) AS FLOAT)" + + +class StdDev(ColumnElement[float]): # pylint: disable=too-many-ancestors + """Represent getting the difference between times in seconds.""" + + expr: ColumnElement[int | float] | SecondsDifference + + _traverse_internals = [ + ("expr", InternalTraversal.dp_clauseelement), + ] + + def __init__( + self, + expr: ColumnElement[int | float] | SecondsDifference, + ): + """Get a clause for the standard deviation of a sample of values.""" + self.expr = expr + + __sa_operate__ = ColumnElement.operate + + +@compiles(StdDev) +def compile_stddev(element: StdDev, compiler: Any, **kw: Any) -> str: + """Create SQL for standard deviation.""" + e = compiler.process(element.expr, **kw) + return f"STDDEV({e})" + + +@compiles(StdDev, "mssql") +def compile_stddev_mssql(element: StdDev, compiler: Any, **kw: Any) -> str: + """MSSQL equivalent: STDEVP.""" + e = compiler.process(element.expr, **kw) + return f"STDEVP({e})" + + +class IsNull(ColumnElement[float]): # pylint: disable=too-many-ancestors + """Represent IS NULL as an expression.""" + + expr: ColumnElement[float] + + _traverse_internals = [ + ("expr", InternalTraversal.dp_clauseelement), + ] + + def __init__( + self, + expr: ColumnElement[float], + ): + """Get the clause that is being tested for nullness.""" + self.expr = expr + + __sa_operate__ = ColumnElement.operate + + +@compiles(IsNull) +def compile_isnull(element: IsNull, compiler: Any, **kw: Any) -> str: + """Create SQL for IS NULL.""" + e = compiler.process(element.expr, **kw) + return f"{e} IS NULL" + + +class IsNotNull(ColumnElement[float]): # pylint: disable=too-many-ancestors + """Represent IS NOT NULL as an expression.""" + + expr: ColumnElement[float] + + _traverse_internals = [ + ("expr", InternalTraversal.dp_clauseelement), + ] + + def __init__( + self, + expr: ColumnElement[float], + ): + """Get the clause that is being tested for nonnullness.""" + self.expr = expr + + __sa_operate__ = ColumnElement.operate + + +@compiles(IsNotNull) +def compile_isnotnull(element: IsNotNull, compiler: Any, **kw: Any) -> str: + """Create SQL for IS NULL.""" + e = compiler.process(element.expr, **kw) + return f"{e} IS NOT NULL" + + +class Random(ColumnElement[float]): # pylint: disable=too-many-ancestors + """Represent a random value suitable for choosing random rows.""" + + _traverse_internals = [] + + def __init__( + self, + ): + """Get a clause for random values.""" + + __sa_operate__ = ColumnElement.operate + + +class NullIf(ColumnElement[Optional[T]]): # pylint: disable=too-many-ancestors + """Represent NULLIF.""" + + expr1: ColumnElement[T] + expr2: ColumnElement[T] + + _traverse_internals = [ + ("expr1", InternalTraversal.dp_clauseelement), + ("expr2", InternalTraversal.dp_clauseelement), + ] + + def __init__( + self, + expr1: ColumnElement[T], + expr2: ColumnElement[T], + ): + """ + Get a NULLIF clause. + + If ``expr1`` = ``expr2`` the result is NULL, otherwise ``expr1``. + """ + self.expr1 = expr1 + self.expr2 = expr2 + + __sa_operate__ = ColumnElement.operate + + +@compiles(NullIf) +def compile_null_if(element: NullIf, compiler: Any, **kw: Any) -> str: + """Create SQL for NULLIF.""" + e1 = compiler.process(element.expr1, **kw) + e2 = compiler.process(element.expr2, **kw) + return f"NULLIF({e1}, {e2})" + + +@compiles(Random) +def compile_random(_element: Random, _compiler: Any, **_kw: Any) -> str: + """Create SQL for random.""" + return "RANDOM()" + + +@compiles(Random, "mssql") +def compile_random_mssql(_element: Random, _compiler: Any, **_kw: Any) -> str: + """ + MSSQL uses NEWID. + + RAND() is the obvious equivalent, but it does not work because the + same random number gets chosen for each row. + """ + return "NEWID()" diff --git a/datafaker/interactive/base.py b/datafaker/interactive/base.py index 5bf1a3a2..b527b41f 100644 --- a/datafaker/interactive/base.py +++ b/datafaker/interactive/base.py @@ -10,7 +10,7 @@ import sqlalchemy from prettytable import PrettyTable -from sqlalchemy import Engine, ForeignKey, MetaData, Table +from sqlalchemy import Engine, ForeignKey, MetaData, Table, func, or_, select from sqlalchemy.exc import DatabaseError, SQLAlchemyError from typing_extensions import Self @@ -19,6 +19,7 @@ fk_refers_to_ignored_table, get_sync_engine, ) +from datafaker.dialects import Random from datafaker.utils import T, get_property @@ -319,14 +320,10 @@ def _remove_prefix_src_stats(self, prefix: str) -> list[MutableMapping[str, Any] self.config["src-stats"] = new_src_stats return new_src_stats - def get_nullable_columns(self, table_name: str) -> list[str]: + def get_nullable_columns(self, table_name: str) -> list[sqlalchemy.Column]: """Get the names of the nullable columns in the named table.""" metadata_table = self.metadata.tables[table_name] - return [ - str(name) - for name, column in metadata_table.columns.items() - if column.nullable - ] + return [column for column in metadata_table.columns.values() if column.nullable] def find_entry_index_by_table_name(self, table_name: str) -> int | None: """Get the index of the table entry of the named table.""" @@ -352,17 +349,14 @@ def do_counts(self, _arg: str) -> None: return table_name = self.table_name() nullable_columns = self.get_nullable_columns(table_name) - colcounts = [f', COUNT("{nnc}") AS "{nnc}"' for nnc in nullable_columns] + tbl = self.table_metadata() + count_exprs = [func.count().label("row_count")] + [ # pylint: disable=E1102 + func.count(tbl.c[col.name]).label(col.name) # pylint: disable=E1102 + for col in nullable_columns + ] + stmt = select(*count_exprs).select_from(tbl) with self.sync_engine.connect() as connection: - result = ( - connection.execute( - sqlalchemy.text( - f'SELECT COUNT(*) AS row_count{"".join(colcounts)} FROM "{table_name}"' - ) - ) - .mappings() - .first() - ) + result = connection.execute(stmt).mappings().first() if result is None: self.print("Could not count rows in table {0}", table_name) return @@ -411,23 +405,24 @@ def do_peek(self, arg: str) -> None: max_peek_rows = 25 if len(self._table_entries) <= self.table_index: return - table_name = self.table_name() col_names = arg.split() if not col_names: col_names = self._get_column_names() - nonnulls = [f'"{cn}" IS NOT NULL' for cn in col_names] + table = self.table_metadata() + col_exprs = [table.columns[cn] for cn in col_names] + nonnull_clauses = [ce.isnot(None) for ce in col_exprs] + stmt = ( + select(*col_exprs) + .select_from(table) + .where(or_(*nonnull_clauses)) + .order_by(Random()) + .limit(max_peek_rows) + ) with self.sync_engine.connect() as connection: - cols = ", ".join(f'"{cn}"' for cn in col_names) - where = "WHERE" if nonnulls else "" - nonnull = " OR ".join(nonnulls) - query = sqlalchemy.text( - f'SELECT {cols} FROM "{table_name}" {where} {nonnull}' - f" ORDER BY RANDOM() LIMIT {max_peek_rows}" - ) try: - result = connection.execute(query) + result = connection.execute(stmt) except SQLAlchemyError as exc: - self.print(self.ERROR_FAILED_SQL, exc=exc, query=query) + self.print(self.ERROR_FAILED_SQL, exc=exc, query=stmt) return self.print_table(list(result.keys()), result.fetchmany(max_peek_rows)) diff --git a/datafaker/interactive/generators.py b/datafaker/interactive/generators.py index e076e24b..310e7423 100644 --- a/datafaker/interactive/generators.py +++ b/datafaker/interactive/generators.py @@ -5,10 +5,10 @@ from dataclasses import dataclass from typing import Any, Callable, Optional, cast -import sqlalchemy -from sqlalchemy import Column +from sqlalchemy import Column, and_, literal_column, select from datafaker.db_utils import MaybeAsyncEngine, primary_private_fks, table_is_private +from datafaker.dialects import Random from datafaker.interactive.base import DbCmd, TableEntry, fk_column_name, or_default from datafaker.proposers import everything_factory from datafaker.proposers.base import PredefinedProposer, Proposer @@ -16,6 +16,7 @@ get_columns_assigned, get_row_generators, logger, + schema_qualified_name, split_column_full_name, ) @@ -61,8 +62,9 @@ def get_aggregate_query( ] if not clauses: return None + qualified = schema_qualified_name(table_name, engine) alias = f' AS "{table_name}"' if engine.dialect.name == "duckdb" else "" - return f'SELECT {", ".join(clauses)} FROM "{table_name}"{alias}' + return f'SELECT {", ".join(clauses)} FROM "{qualified}"{alias}' # pylint: disable=too-many-public-methods @@ -779,15 +781,17 @@ def _get_column_data( self, count: int, to_str: Callable[[Any], str] = repr ) -> list[list[str]]: columns = self._get_column_names() - columns_string = ", ".join(columns) - pred = " AND ".join(f"{column} IS NOT NULL" for column in columns) + col_exprs = [literal_column(col) for col in columns] + nonnull_clauses = [literal_column(col).isnot(None) for col in columns] + stmt = ( + select(*col_exprs) + .select_from(self.table_metadata()) + .where(and_(*nonnull_clauses)) + .order_by(Random()) + .limit(count) + ) with self.sync_engine.connect() as connection: - result = connection.execute( - sqlalchemy.text( - f'SELECT {columns_string} FROM "{self.table_name()}"' - f" WHERE {pred} ORDER BY RANDOM() LIMIT {count}" - ) - ) + result = connection.execute(stmt) return [[to_str(x) for x in xs] for xs in result.all()] def do_propose(self, _arg: str) -> None: diff --git a/datafaker/interactive/missingness.py b/datafaker/interactive/missingness.py index 74eaaf64..60940a36 100644 --- a/datafaker/interactive/missingness.py +++ b/datafaker/interactive/missingness.py @@ -4,6 +4,10 @@ from dataclasses import dataclass from typing import cast +from sqlalchemy import Column, Dialect, Table, func, select +from sqlalchemy.sql.elements import literal_column + +from datafaker.dialects import IsNull, Random from datafaker.interactive.base import DbCmd, TableEntry @@ -12,36 +16,49 @@ class MissingnessType: """The functions required for applying missingness.""" SAMPLED = "column_presence.sampled" - SAMPLED_QUERY = ( - "SELECT COUNT(*) AS row_count, {result_names} FROM " - '(SELECT {column_is_nulls} FROM "{table}" ORDER BY RANDOM() LIMIT {count})' - " AS __t GROUP BY {result_names}" - ) name: str query: str comments: list[str] - columns: list[str] + columns: list[Column] @classmethod - def sampled_query(cls, table: str, count: int, column_names: Iterable[str]) -> str: + def sampled_query( + cls, + table: Table, + count: int, + columns: Iterable[Column], + dialect: Dialect, + ) -> str: """ Construct a query to make a sampling of the named rows of the table. - :param table: The name of the table to sample. + :param table: The table to sample. :param count: The number of samples to get. - :param column_names: The columns to fetch. + :param columns: The columns to fetch. + :param dialect: The SQLAlchemy dialect (e.g. ``mssql.dialect()``). :return: The SQL query to do the sampling. """ - result_names = ", ".join([f"{c}__is_null" for c in column_names]) - column_is_nulls = ", ".join( - [f"{c} IS NULL AS {c}__is_null" for c in column_names] + results = [IsNull(c).label(c.name + "__is_null") for c in columns] + subquery = ( + select(*results) + .select_from(table) + .order_by(Random()) + .limit(literal_column(str(count))) + .subquery("__t") ) - return cls.SAMPLED_QUERY.format( - result_names=result_names, - column_is_nulls=column_is_nulls, - table=table, - count=count, + result_labels = [subquery.c[r.name].label(r.name) for r in results] + query = ( + select( + func.count().label("row_count"), *result_labels # pylint: disable=E1102 + ) + .select_from(subquery) + .group_by(*result_labels) + .compile( + dialect=dialect, + compile_kwargs={"literal_binds": True}, + ) ) + return str(query) @dataclass @@ -115,6 +132,7 @@ def make_table_entry( columns=[], ) elif len(mgs) == 1: + table = self.metadata.tables[table_name] mg = mgs[0] mg_name = mg.get("name", None) if isinstance(mg_name, str): @@ -125,7 +143,10 @@ def make_table_entry( name=mg_name, query=query, comments=comments, - columns=mg.get("columns_assigned", []), + columns=[ + table.columns[colname] + for colname in mg.get("columns_assigned", []) + ], ) if old is None: return None @@ -194,7 +215,7 @@ def _copy_entries(self) -> None: "kwargs": { "patterns": f'SRC_STATS["{src_stat_key}"]["results"]' }, - "columns": entry.new_type.columns, + "columns": [c.name for c in entry.new_type.columns], } ] src_stats.append( @@ -327,9 +348,10 @@ def do_sampled(self, arg: str) -> None: self._set_type( MissingnessType.SAMPLED, MissingnessType.sampled_query( - entry.name, + self.metadata.tables[entry.name], count, self.get_nullable_columns(entry.name), + dialect=self.sync_engine.dialect, ), [ "The missingness patterns and how often they appear in a" diff --git a/datafaker/interactive/table.py b/datafaker/interactive/table.py index c32913a2..7da8d2ae 100644 --- a/datafaker/interactive/table.py +++ b/datafaker/interactive/table.py @@ -3,8 +3,9 @@ from dataclasses import dataclass from typing import Any, cast -import sqlalchemy +from sqlalchemy import func, literal_column, select +from datafaker.dialects import Random from datafaker.interactive.base import ( TYPE_LETTER, TYPE_PROMPT, @@ -477,16 +478,20 @@ def print_column_data(self, column: str, count: int, min_length: int) -> None: :param count: The number of rows to sample. :param min_length: The minimum length of text to choose from (0 for any text). """ - where = f"WHERE {column} IS NOT NULL" + col_expr = literal_column(column) if 0 < min_length: - where = f"WHERE LENGTH({column}) >= {min_length}" + where_clause = func.length(col_expr) >= min_length + else: + where_clause = col_expr.isnot(None) + stmt = ( + select(col_expr) + .select_from(self.table_metadata()) + .where(where_clause) + .order_by(Random()) + .limit(count) + ) with self.sync_engine.connect() as connection: - result = connection.execute( - sqlalchemy.text( - f'SELECT {column} FROM "{self.table_name()}"' - f" {where} ORDER BY RANDOM() LIMIT {count}" - ) - ) + result = connection.execute(stmt) self.columnize([str(x[0]) for x in result.all()]) def print_row_data(self, count: int) -> None: @@ -495,12 +500,9 @@ def print_row_data(self, count: int) -> None: :param count: The number of rows to report. """ + stmt = select(self.table_metadata()).order_by(Random()).limit(count) with self.sync_engine.connect() as connection: - result = connection.execute( - sqlalchemy.text( - f'SELECT * FROM "{self.table_name()}" ORDER BY RANDOM() LIMIT {count}' - ) - ) + result = connection.execute(stmt) if result is None: self.print("No rows in this table!") return diff --git a/datafaker/main.py b/datafaker/main.py index baf2d49a..ee1269ae 100644 --- a/datafaker/main.py +++ b/datafaker/main.py @@ -32,6 +32,7 @@ from datafaker.interactive.base import DbCmd from datafaker.make import make_src_stats, make_tables_file, make_vocabulary_tables from datafaker.remove import remove_db_data, remove_db_tables, remove_db_vocab +from datafaker.serialize_metadata import dict_to_metadata, should_ignore_fk from datafaker.settings import ( SettingsError, get_destination_dsn, @@ -48,13 +49,12 @@ read_config_file, ) -from .serialize_metadata import dict_to_metadata, should_ignore_fk - # pylint: disable=too-many-arguments ORM_FILENAME: Final[str] = "orm.yaml" CONFIG_FILENAME: Final[str] = "config.yaml" STATS_FILENAME: Final[str] = "src-stats.yaml" +DF_FILENAME: Final[str] = "df.py" app = Typer(no_args_is_help=True) @@ -65,6 +65,17 @@ def datafaker() -> None: app() except OperationalError as exc: logger.error(str(exc)) + if ( + type(exc.orig).__module__ == "pyodbc" + and isinstance(exc.orig, BaseException) + and 0 < len(exc.orig.args) + and exc.orig.args[0] == "HYT00" + ): + logger.error( + "Please ensure that the ODBC driver is installed and registered," + " and that the database server is available at the location specified." + ) + logger.error("(see the installation instructions)") # Outside of app() typer.Exit(1) doesn't work sys.exit(1) except SettingsError as exc: @@ -143,169 +154,44 @@ def main( conf_logger(verbose) -@app.command() -def create_data( - orm_file: Path = Option( - ORM_FILENAME, - help="The name of the ORM yaml file", - dir_okay=False, - ), - config_file: Optional[Path] = Option( - CONFIG_FILENAME, - help="The configuration file", +@app.command(rich_help_panel="Configure and Extract") +def make_tables( + orm_file: Path = Option(ORM_FILENAME, help="Path to write the ORM yaml file to"), + force: bool = Option( + False, "--force", "-f", help="Overwrite any existing orm yaml file." ), - stats_file: Optional[Path] = Option( + parquet_dir: Optional[Path] = Option( None, help=( - "Statistics file (output of make-stats); default is src-stats.yaml if the " - "config file references SRC_STATS, or None otherwise." + "Directory of Parquet files to consider part of the database." + " This can be useful when using DuckDB." + " Make sure you check the output!" ), - show_default=False, - dir_okay=False, - ), - num_passes: int = Option(1, help="Number of passes (rows or stories) to make"), -) -> None: - """Populate the schema in the target directory with synthetic data. - - This CLI command generates synthetic data for - Python table structures, and inserts these rows - into a destination schema. - - Also takes as input object relational model as represented - by file containing Python classes and its attributes. - - Takes as input datafaker output as represented by Python - classes, its attributes and methods for generating values - for those attributes. - - Final input is the number of rows required. - - Example: - $ datafaker create-data - """ - logger.debug("Creating data.") - config = read_config_file(config_file) if config_file is not None else {} - if stats_file is None and generators_require_stats(config): - stats_file = Path(STATS_FILENAME) - orm_metadata = load_metadata_for_output(orm_file, config) - try: - row_counts = create_db_data( - sorted_non_vocabulary_tables(orm_metadata, config), - config, - stats_file, - num_passes, - orm_metadata, - ) - logger.debug( - "Data created in %s %s.", - num_passes, - "pass" if num_passes == 1 else "passes", - ) - for table_name, row_count in row_counts.items(): - logger.debug( - "%s: %s %s created.", - table_name, - row_count, - "row" if row_count == 1 else "rows", - ) - return - except RuntimeError as e: - logger.error(e.args[0]) - except SettingsError as e: - logger.error(str(e)) - raise Exit(1) - - -@app.command() -def create_vocab( - orm_file: Path = Option( - ORM_FILENAME, - help="The name of the ORM yaml file", - dir_okay=False, - ), - config_file: Path = Option( - CONFIG_FILENAME, - help="The configuration file", - dir_okay=False, - ), -) -> None: - """Import vocabulary data into the target database. - - Example: - $ datafaker create-vocab - """ - logger.debug("Loading vocab.") - config = read_config_file(config_file) if config_file is not None else {} - meta_dict = load_metadata_config(orm_file, config) - orm_metadata = dict_to_metadata(meta_dict, config) - vocabs_loaded = create_db_vocab(orm_metadata, meta_dict, config) - num_vocabs = len(vocabs_loaded) - logger.debug("%s %s loaded.", num_vocabs, "table" if num_vocabs == 1 else "tables") - - -@app.command() -def create_tables( - orm_file: Path = Option( - ORM_FILENAME, - help="The name of the ORM yaml file", - dir_okay=False, - ), - config_file: Optional[Path] = Option( - CONFIG_FILENAME, - help="The configuration file", - dir_okay=False, + file_okay=False, + dir_okay=True, ), ) -> None: - """Create schema from the ORM YAML file. - - This CLI command creates the destination schema using object - relational model declared as Python tables. + """Make a YAML file representing the tables in the schema. Example: - $ datafaker create-tables + $ datafaker make_tables """ - logger.debug("Creating tables.") - config = read_config_file(config_file) if config_file is not None else {} - orm_metadata = load_metadata_for_output(orm_file, config) - create_db_tables(orm_metadata) - logger.debug("Tables created.") + logger.debug("Creating %s.", orm_file) + orm_file_path = Path(orm_file) + if not force: + _check_file_non_existence(orm_file_path) -@app.command() -def create_generators( - _orm_file: Path = Option( - ORM_FILENAME, - help="The name of the ORM yaml file", - dir_okay=False, - ), - _df_file: Path = Option( - None, - help="Path to write Python generators to.", - dir_okay=False, - ), - _config_file: Path = Option( - CONFIG_FILENAME, - help="The configuration file", - dir_okay=False, - ), - _stats_file: Optional[Path] = Option( - None, - help=( - "Statistics file (output of make-stats); default is src-stats.yaml if the " - "config file references SRC_STATS, or None otherwise." - ), - show_default=False, - dir_okay=False, - ), - _force: bool = Option( - False, "--force", "-f", help="Overwrite any existing Python generators file." - ), -) -> None: - """Obsolete command.""" - logger.error("This command is deprecated; it does nothing.") + content = make_tables_file( + get_source_dsn(), + get_source_schema(), + parquet_dir, + ) + orm_file_path.write_text(content, encoding="utf-8") + logger.debug("%s created.", orm_file) -@app.command() +@app.command(rich_help_panel="Configure and Extract") def make_vocab( orm_file: Path = Option( ORM_FILENAME, @@ -344,82 +230,7 @@ def make_vocab( ) -@app.command() -def make_stats( - orm_file: Path = Option( - ORM_FILENAME, - help="The name of the ORM yaml file", - dir_okay=False, - ), - config_file: Optional[Path] = Option( - CONFIG_FILENAME, - help="The configuration file", - dir_okay=False, - ), - stats_file: Path = Option(STATS_FILENAME), - force: bool = Option( - False, "--force", "-f", help="Overwrite any existing vocabulary file." - ), -) -> None: - """Compute summary statistics from the source database.""" - logger.debug("Creating %s.", stats_file) - - if not force: - _check_file_non_existence(stats_file) - - config = read_config_file(config_file) if config_file is not None else {} - meta_dict = load_metadata_config(orm_file, config) - - src_stats = asyncio.get_event_loop().run_until_complete( - make_src_stats( - get_source_dsn(), - config, - get_source_schema(), - parquet_dir=meta_dict.get("parquet-dir", None), - ) - ) - stats_file.write_text(yaml.dump(src_stats), encoding="utf-8") - logger.debug("%s created.", stats_file) - - -@app.command() -def make_tables( - orm_file: Path = Option(ORM_FILENAME, help="Path to write the ORM yaml file to"), - force: bool = Option( - False, "--force", "-f", help="Overwrite any existing orm yaml file." - ), - parquet_dir: Optional[Path] = Option( - None, - help=( - "Directory of Parquet files to consider part of the database." - " This can be useful when using DuckDB." - " Make sure you check the output!" - ), - file_okay=False, - dir_okay=True, - ), -) -> None: - """Make a YAML file representing the tables in the schema. - - Example: - $ datafaker make_tables - """ - logger.debug("Creating %s.", orm_file) - - orm_file_path = Path(orm_file) - if not force: - _check_file_non_existence(orm_file_path) - - content = make_tables_file( - get_source_dsn(), - get_source_schema(), - parquet_dir, - ) - orm_file_path.write_text(content, encoding="utf-8") - logger.debug("%s created.", orm_file) - - -@app.command() +@app.command(rich_help_panel="Configure and Extract") def configure_tables( config_file: Path = Option( CONFIG_FILENAME, @@ -457,7 +268,54 @@ def configure_tables( logger.debug("Tables configured in %s.", config_file) -@app.command() +@app.command(rich_help_panel="Configure and Extract") +def configure_generators( + config_file: Path = Option( + CONFIG_FILENAME, + help="Path of the configuration file to alter", + dir_okay=False, + ), + orm_file: Path = Option( + ORM_FILENAME, + help="The name of the ORM yaml file", + dir_okay=False, + ), + spec: Path = Option( + None, + help=( + "CSV file (headerless) with fields table-name," + " column-name, generator-name to set non-interactively" + ), + ), +) -> None: + """Interactively set generators for column data.""" + logger.debug("Configuring generators in %s.", config_file) + config = {} + if config_file.exists(): + config = yaml.load( + config_file.read_text(encoding="UTF-8"), Loader=yaml.SafeLoader + ) + meta_dict = load_metadata_config(orm_file) + metadata = dict_to_metadata(meta_dict, None) + config_updated = update_config_generators( + DbCmd.Settings( + get_source_dsn(), + get_source_schema(), + config, + metadata, + meta_dict.get("parquet-dir", None), + ), + spec_path=spec, + ) + if config_updated is None: + logger.debug("Cancelled") + return + content = yaml.dump(config_updated) + config_file.write_text(content, encoding="utf-8") + logger.debug("Generators configured in %s.", config_file) + + +@app.command(rich_help_panel="Configure and Extract") def configure_missing( config_file: Path = Option( CONFIG_FILENAME, @@ -493,54 +351,173 @@ def configure_missing( return content = yaml.dump(config_updated) config_file.write_text(content, encoding="utf-8") - logger.debug("Missingness generators in %s.", config_file) + logger.debug("Generators missingness in %s.", config_file) -@app.command() -def configure_generators( +@app.command(rich_help_panel="Configure and Extract") +def make_stats( + orm_file: Path = Option( + ORM_FILENAME, + help="The name of the ORM yaml file", + dir_okay=False, + ), + config_file: Optional[Path] = Option( + CONFIG_FILENAME, + help="The configuration file", + dir_okay=False, + ), + stats_file: Path = Option(STATS_FILENAME), + force: bool = Option( + False, "--force", "-f", help="Overwrite any existing vocabulary file." + ), +) -> None: + """Compute summary statistics from the source database.""" + logger.debug("Creating %s.", stats_file) + + if not force: + _check_file_non_existence(stats_file) + + config = read_config_file(config_file) if config_file is not None else {} + meta_dict = load_metadata_config(orm_file, config) + + src_stats = asyncio.get_event_loop().run_until_complete( + make_src_stats( + get_source_dsn(), + config, + get_source_schema(), + parquet_dir=meta_dict.get("parquet-dir", None), + ) + ) + stats_file.write_text(yaml.dump(src_stats), encoding="utf-8") + logger.debug("%s created.", stats_file) + + +@app.command(rich_help_panel="Create Synthetic Database") +def create_tables( + orm_file: Path = Option( + ORM_FILENAME, + help="The name of the ORM yaml file", + dir_okay=False, + ), + config_file: Optional[Path] = Option( + CONFIG_FILENAME, + help="The configuration file", + dir_okay=False, + ), +) -> None: + """Create schema from the ORM YAML file. + + This CLI command creates the destination schema using object + relational model declared as Python tables. + + Example: + $ datafaker create-tables + """ + logger.debug("Creating tables.") + config = read_config_file(config_file) if config_file is not None else {} + orm_metadata = load_metadata_for_output(orm_file, config) + create_db_tables(orm_metadata) + logger.debug("Tables created.") + + +@app.command(rich_help_panel="Create Synthetic Database") +def create_vocab( + orm_file: Path = Option( + ORM_FILENAME, + help="The name of the ORM yaml file", + dir_okay=False, + ), config_file: Path = Option( CONFIG_FILENAME, - help="Path of the configuration file to alter", + help="The configuration file", dir_okay=False, ), +) -> None: + """Import vocabulary data into the target database. + + Example: + $ datafaker create-vocab + """ + logger.debug("Loading vocab.") + config = read_config_file(config_file) if config_file is not None else {} + meta_dict = load_metadata_config(orm_file, config) + orm_metadata = dict_to_metadata(meta_dict, config) + vocabs_loaded = create_db_vocab(orm_metadata, meta_dict, config) + num_vocabs = len(vocabs_loaded) + logger.debug("%s %s loaded.", num_vocabs, "table" if num_vocabs == 1 else "tables") + + +@app.command(rich_help_panel="Create Synthetic Database") +def create_data( orm_file: Path = Option( ORM_FILENAME, help="The name of the ORM yaml file", dir_okay=False, ), - spec: Path = Option( + config_file: Optional[Path] = Option( + CONFIG_FILENAME, + help="The configuration file", + ), + stats_file: Optional[Path] = Option( None, help=( - "CSV file (headerless) with fields table-name," - " column-name, generator-name to set non-interactively" + "Statistics file (output of make-stats); default is src-stats.yaml if the " + "config file references SRC_STATS, or None otherwise." ), + show_default=False, + dir_okay=False, ), + num_passes: int = Option(1, help="Number of passes (rows or stories) to make"), ) -> None: - """Interactively set generators for column data.""" - logger.debug("Configuring generators in %s.", config_file) - config = {} - if config_file.exists(): - config = yaml.load( - config_file.read_text(encoding="UTF-8"), Loader=yaml.SafeLoader - ) - meta_dict = load_metadata_config(orm_file) - metadata = dict_to_metadata(meta_dict, None) - config_updated = update_config_generators( - DbCmd.Settings( - get_source_dsn(), - get_source_schema(), + """Populate the schema in the target directory with synthetic data. + + This CLI command generates synthetic data for + Python table structures, and inserts these rows + into a destination schema. + + Also takes as input object relational model as represented + by file containing Python classes and its attributes. + + Takes as input datafaker output as represented by Python + classes, its attributes and methods for generating values + for those attributes. + + Final input is the number of rows required. + + Example: + $ datafaker create-data + """ + logger.debug("Creating data.") + config = read_config_file(config_file) if config_file is not None else {} + if stats_file is None and generators_require_stats(config): + stats_file = Path(STATS_FILENAME) + orm_metadata = load_metadata_for_output(orm_file, config) + try: + row_counts = create_db_data( + sorted_non_vocabulary_tables(orm_metadata, config), config, - metadata, - meta_dict.get("parquet-dir", None), - ), - spec_path=spec, - ) - if config_updated is None: - logger.debug("Cancelled") + stats_file, + num_passes, + orm_metadata, + ) + logger.debug( + "Data created in %s %s.", + num_passes, + "pass" if num_passes == 1 else "passes", + ) + for table_name, row_count in row_counts.items(): + logger.debug( + "%s: %s %s created.", + table_name, + row_count, + "row" if row_count == 1 else "rows", + ) return - content = yaml.dump(config_updated) - config_file.write_text(content, encoding="utf-8") - logger.debug("Generators configured in %s.", config_file) + except RuntimeError as e: + logger.error(e.args[0]) + except SettingsError as e: + logger.error(str(e)) + raise Exit(1) def convert_table_names_to_tables( @@ -612,7 +589,7 @@ def _dump_tables_to_directory( logger.warning("Failed to write %s", f) -@app.command() +@app.command(rich_help_panel="Inspect and Export") def dump_data( config_file: Optional[Path] = Option( CONFIG_FILENAME, @@ -662,7 +639,7 @@ def dump_data( mtables = convert_table_names_to_tables(table, metadata) if not mtables: mtables = generated_tables(metadata, config) - if output == "-": + if output is not None and output.name == "-": _dump_csv_to_stdout(mtables[0], metadata, dst_dsn, schema_name) return writer = _get_writer(parquet, output, metadata, dst_dsn, schema_name) @@ -674,7 +651,7 @@ def dump_data( _dump_tables_to_directory(writer, directory, mtables) -@app.command() +@app.command(rich_help_panel="Inspect and Export") def validate_config( config_file: Path = Argument(help="The configuration file to validate"), ) -> None: @@ -691,7 +668,7 @@ def validate_config( logger.debug("Config file is valid.") -@app.command() +@app.command(rich_help_panel="Remove Destination Data") def remove_data( orm_file: Path = Option( ORM_FILENAME, @@ -718,7 +695,7 @@ def remove_data( logger.info("Would truncate non-vocabulary tables if called with --yes.") -@app.command() +@app.command(rich_help_panel="Remove Destination Data") def remove_vocab( orm_file: Path = Option( ORM_FILENAME, @@ -746,7 +723,7 @@ def remove_vocab( logger.info("Would truncate vocabulary tables if called with --yes.") -@app.command() +@app.command(rich_help_panel="Remove Destination Data") def remove_tables( orm_file: Path = Option( ORM_FILENAME, @@ -797,7 +774,7 @@ class TableType(str, Enum): GENERATED = "generated" -@app.command() +@app.command(rich_help_panel="Inspect and Export") def list_tables( orm_file: Path = Option( ORM_FILENAME, @@ -830,7 +807,7 @@ def list_tables( print(name) -@app.command() +@app.command(rich_help_panel="Inspect and Export") def version() -> None: """Display version information.""" assert __package__ is not None diff --git a/datafaker/make.py b/datafaker/make.py index 88d3b383..713a01cd 100644 --- a/datafaker/make.py +++ b/datafaker/make.py @@ -15,7 +15,7 @@ import yaml from mimesis.providers.base import BaseProvider from sqlalchemy import CursorResult, Engine, MetaData, text -from sqlalchemy.dialects import postgresql +from sqlalchemy.dialects import mssql, postgresql from sqlalchemy.engine import Connection from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine from sqlalchemy.schema import ( @@ -195,11 +195,8 @@ def _get_row_generator( return row_gen_info, columns_covered -def _get_default_generator(column: Column) -> RowGeneratorInfo: +def _get_default_generator(column: Column) -> RowGeneratorInfo | None: """Get default generator information, for the given column.""" - # If it's a primary key column, we presume that primary keys are populated - # automatically. - # If it's a foreign key column, pull random values from the column it # references. variable_names: list[str] = [] @@ -312,10 +309,7 @@ class GeneratorInfo: # Name or function to generate random objects of this type (not using summary data) generator: str | Callable[[Column], tuple[str, dict[str, str]]] - # SQL query that gets the data to supply as arguments to the generator - # ({column} and {table} will be interpolated) - summary_query: str | None = None - # Dictionary of the names returned from the summary_query to arg types. + # Dictionary of arg types for any summary query. # An arg type is a callable turning the returned value into a Python type to # pass as an argument to the generator. arg_types: dict[str, Callable] = field(default_factory=dict) @@ -352,12 +346,10 @@ def get_result_mappings( ), sqltypes.Date: GeneratorInfo( generator="generic.datetime.date", - summary_query=_YEAR_SUMMARY_QUERY, arg_types={"start": int, "end": int}, ), sqltypes.DateTime: GeneratorInfo( generator="generic.datetime.datetime", - summary_query=_YEAR_SUMMARY_QUERY, arg_types={"start": int, "end": int}, ), sqltypes.Integer: GeneratorInfo( # must be before Numeric @@ -379,6 +371,9 @@ def get_result_mappings( postgresql.UUID: GeneratorInfo( generator="generic.cryptographic.uuid", ), + mssql.UNIQUEIDENTIFIER: GeneratorInfo( + generator="generic.cryptographic.uuid", + ), sqltypes.String: GeneratorInfo( generator=_string_generator, choice=True, @@ -508,7 +503,9 @@ def _get_generator_for_table( for column in table.columns: if column.name not in columns_covered: - table_data.row_gens.append(_get_default_generator(column)) + gen = _get_default_generator(column) + if gen is not None: + table_data.row_gens.append(gen) return table_data @@ -701,11 +698,13 @@ def make_tables_file( db_dsn: str, schema_name: Optional[str], parquet_dir: Optional[Path] = None, + engine: Optional[Engine] = None, ) -> str: """Construct the YAML file representing the schema.""" - engine = get_sync_engine(create_db_engine(db_dsn, schema_name=schema_name)) + if engine is None: + engine = get_sync_engine(create_db_engine(db_dsn, schema_name=schema_name)) - metadata = get_metadata(engine) + metadata = get_metadata(engine, schema_name=schema_name) meta_dict = metadata_to_dict(metadata, schema_name, engine, parquet_dir) if parquet_dir is not None: @@ -846,10 +845,8 @@ async def make_src_stats_connection( ) src_stats = { query_block["name"]: { - "queries": { - "date": date_string, - "query": query_block["query"], - }, + "query_date": date_string, + "query": query_block["query"], "comments": query_block.get("comments", []), "results": fix_types(result), } diff --git a/datafaker/populate.py b/datafaker/populate.py index 860c69e7..2f85581d 100644 --- a/datafaker/populate.py +++ b/datafaker/populate.py @@ -257,7 +257,7 @@ def set_context(self, context: Mapping) -> None: """Set all the Python symbols that must be known to the configuration.""" self.context = {**context} - def __call__(self, db_conn: sqlalchemy.Connection) -> dict[str, Any]: + def generate_row(self, _db_conn: sqlalchemy.Connection) -> dict[str, Any]: """Generate some rows of the relevant table in the database.""" result: dict[str, Any] = {} self.context["GENERATED_ROW"] = result diff --git a/datafaker/proposers/__init__.py b/datafaker/proposers/__init__.py index 22a0c954..9f705fa1 100644 --- a/datafaker/proposers/__init__.py +++ b/datafaker/proposers/__init__.py @@ -36,6 +36,8 @@ def everything_factory(config: Mapping, metadata: MetaData) -> ProposerFactory: Get a factory that encapsulates all the other factories. :param config: The ``config.yaml`` configuration. + :param metadata: The metadata of the source database. + :return: A factory that is capable of returning any applicable proposers. """ return MultiProposerFactory( MimesisStringProposerFactory(), @@ -50,7 +52,7 @@ def everything_factory(config: Mapping, metadata: MetaData) -> ProposerFactory: ConstantProposerFactory(), MultivariateNormalProposerFactory(), MultivariateLogNormalProposerFactory(), - NullPartitionedNormalProposerFactory(config), - NullPartitionedLogNormalProposerFactory(config), + NullPartitionedNormalProposerFactory(config, metadata), + NullPartitionedLogNormalProposerFactory(config, metadata), DateAfterProposerFactory(config, metadata), ) diff --git a/datafaker/proposers/base.py b/datafaker/proposers/base.py index 617d4284..72206e6c 100644 --- a/datafaker/proposers/base.py +++ b/datafaker/proposers/base.py @@ -9,15 +9,10 @@ import mimesis.locales from sqlalchemy import Column, Engine, Join, Table, func, select from sqlalchemy.exc import DatabaseError -from sqlalchemy.sql.selectable import NamedFromClause -from sqlalchemy.sql.visitors import ( - ExternallyTraversible, - replacement_traverse, - traverse, -) from sqlalchemy.types import Integer, Numeric, String, TypeEngine from typing_extensions import Self +from datafaker.dialects import StdDev from datafaker.providers import DistributionProvider from datafaker.utils import logger @@ -127,9 +122,6 @@ def custom_queries(self) -> dict[str, dict[str, Any]]: - SELECT AVG("table".column) FROM "table" WHERE "table".column > 3 - SELECT AVG(a.column) FROM table AS a WHERE a.column > 3 - - Or, if you are using the SQLAlchemy ORM, pass the query through - ``duckdb_workaround`` before compiling it. """ return {} @@ -163,7 +155,9 @@ class PredefinedProposer(Proposer): that have been defined previously. """ - SELECT_AGGREGATE_RE = re.compile(r"SELECT (.*) FROM ([A-Za-z_][A-Za-z0-9_]*)") + SELECT_AGGREGATE_RE = re.compile( + r"SELECT (.*) FROM ((?:[A-Za-z_][A-Za-z0-9_]*\.)?[A-Za-z_][A-Za-z0-9_]*)" + ) AS_CLAUSE_RE = re.compile(r" *(.+) +AS +([A-Za-z_][A-Za-z0-9_]*) *") SRC_STAT_NAME_RE = re.compile(r'\bSRC_STATS\["([^]]*)"\].*') @@ -220,7 +214,7 @@ def __init__( # This query is one that this generator is interested in sam = None if query is None else self.SELECT_AGGREGATE_RE.match(query) # sam.group(2) is the table name from the FROM clause of the query - if sam and name == f"auto__{sam.group(2)}": + if sam and name == f"auto__{sam.group(2).split('.')[-1]}": # name is auto__{table_name}, so it's a select_aggregate, # so we split up its clauses sacs = [ @@ -290,57 +284,6 @@ def get_proposers( """Get the proposers appropriate to these columns.""" -class TableReplacer: - """ - Replaces tables with aliased tables. - - We need this to work around a DuckDB problem: - If we are using the ORM code to select a column ``c`` from a table - ``t.parquet``, then DuckDB expects the SQL - ``SELECT "t.parquet".c FROM "t.parquet"`` if ``t.parquet`` is an actual - table in the database, or ``SELECT t.c FROM "t.parquet"`` if ``t.parquet`` - names a file. The best way around this seems to be to use an aliased table, - which works in both cases: ``SELECT a.c FROM "t.parquet" AS a``, and the - best way for that to happen seems to be to use ``replacement_traverse``. - """ - - def __init__(self, table: Table) -> None: - """Initialise with the table to be aliased.""" - self.table = table - self.atable = table.alias(f"_{table.name}__alias") - - def replace( - self, obj: ExternallyTraversible, **_kw: Any - ) -> ExternallyTraversible | None: - """Replace columns with the same column on the aliased table.""" - if isinstance(obj, Column): - if obj.table == self.table: - return self.atable.columns[obj.name] - elif isinstance(obj, Table): - return self.atable - return None - - def aliased_table(self) -> NamedFromClause: - """Get the aliased table.""" - return self.atable - - -def duckdb_workaround(stmt: ExternallyTraversible) -> Any: - """ - Transform a SQLAlchemy ORM statement to work around DuckDB issues. - - :param stmt: An ORM statement, such as the return value of ``select``. - :return: An ORM statement, transformed if necessary. - """ - tables: list[Table] = [] - traverse(stmt, {}, {"table": tables.append}) - for t in tables: - tr = TableReplacer(t) - opts: Mapping[str, Any] = {} - stmt = replacement_traverse(stmt, opts, tr.replace) # type: ignore - return stmt - - def fit_from_buckets(xs: Sequence[NumericType], ys: Sequence[NumericType]) -> float: """Calculate the fit by comparing a pair of lists of buckets.""" sum_diff_squared = sum(map(lambda t, a: (t - a) * (t - a), xs, ys)) @@ -392,8 +335,8 @@ def __init__( # catches errors if SQLAlchemy returns something that # isn't a number for some other unknown reason. pass - self.mean = mean - self.stddev = stddev + self.mean = mean + self.stddev = stddev @classmethod def make_buckets( @@ -414,15 +357,11 @@ def make_buckets( """ with engine.connect() as connection: result = connection.execute( - duckdb_workaround( - select( - func.avg(column).label("mean"), - func.stddev(column).label("stddev"), - func.count(column).label( # pylint: disable=not-callable - "count" - ), - ).select_from(table) - ) + select( + func.avg(column).label("mean"), + StdDev(column).label("stddev"), + func.count(column).label("count"), # pylint: disable=not-callable + ).select_from(table) ).first() if result is None or result.stddev is None or getattr(result, "count") < 2: return None diff --git a/datafaker/proposers/choice.py b/datafaker/proposers/choice.py index ed4c4710..acf0e1f4 100644 --- a/datafaker/proposers/choice.py +++ b/datafaker/proposers/choice.py @@ -6,14 +6,26 @@ from abc import abstractmethod from typing import Any, Sequence, Union -from sqlalchemy import Column, CursorResult, Engine, text +from sqlalchemy import ( + Column, + CursorResult, + Engine, + desc, + func, + literal_column, + select, + table, + text, +) +from datafaker.dialects import Random from datafaker.proposers.base import ( Proposer, ProposerFactory, dist_gen, fit_from_buckets, ) +from datafaker.utils import schema_qualified_name NumericType = Union[int, float] @@ -44,6 +56,61 @@ def zipf_distribution(total: int, bins: int) -> typing.Generator[int, None, None yield x +def _choice_stmt( # pylint: disable=R0913,R0917 + column_name: str, + table_name: str, + store_counts: bool, + sample_count: int | None, + suppress_count: int, + table_sql: str | None = None, +) -> Any: + """Build a SQLAlchemy SELECT for gathering choice value distributions. + + Compiles to dialect-correct SQL: LIMIT/random() on PostgreSQL/DuckDB, + TOP/newid() on MS-SQL. MS-SQL also forbids ORDER BY inside a subquery + without TOP; this function never emits such a clause. + """ + col = literal_column(f'"{column_name}"') + tbl = text(table_sql) if table_sql else table(table_name) + if sample_count is not None: + sample_sub = ( + select(col.label("value")) + .where(col.isnot(None)) + .select_from(tbl) + .order_by(Random()) + .limit(sample_count) + .subquery("_inner") + ) + counted_sub = ( + select( + sample_sub.c.value, + func.count(sample_sub.c.value).label("count"), # pylint: disable=E1102 + ) + .group_by(sample_sub.c.value) + .subquery("_counted") + ) + else: + counted_sub = ( + select( + col.label("value"), + func.count(col).label("count"), # pylint: disable=E1102 + ) + .where(col.isnot(None)) + .select_from(tbl) + .group_by(col) + .subquery("_counted") + ) + out_cols = [counted_sub.c.value] + if store_counts: + out_cols.append(counted_sub.c["count"]) + stmt = select(*out_cols).select_from(counted_sub) + if suppress_count > 0: + stmt = stmt.where(counted_sub.c["count"] > suppress_count) + else: + stmt = stmt.order_by(desc(counted_sub.c["count"])) + return stmt + + class ChoiceProposer(Proposer): """Base proposer for all proposers producing choices of items.""" @@ -58,6 +125,8 @@ def __init__( counts: list[int], sample_count: int | None = None, suppress_count: int = 0, + dialect: Any = None, + table_sql: str | None = None, ) -> None: """Initialise a ChoiceProposer.""" super().__init__() @@ -67,33 +136,28 @@ def __init__( estimated_counts = self.get_estimated_counts(counts) self._fit = fit_from_buckets(counts, estimated_counts) - extra_results = "" - extra_expo = "" - extra_comment = "" - if self.STORE_COUNTS: - extra_results = f", COUNT({column_name}) AS count" - extra_expo = ", count" - extra_comment = " and their counts" + extra_comment = " and their counts" if self.STORE_COUNTS else "" + stmt = _choice_stmt( + column_name, + table_name, + self.STORE_COUNTS, + sample_count, + suppress_count, + table_sql=table_sql, + ) + compile_opts: dict[str, Any] = {"compile_kwargs": {"literal_binds": True}} + if dialect is not None: + compile_opts["dialect"] = dialect + self._query = str(stmt.compile(**compile_opts)) + if suppress_count == 0: if sample_count is None: - self._query = ( - f'SELECT {column_name} AS value{extra_results} FROM "{table_name}"' - f" WHERE {column_name} IS NOT NULL GROUP BY value" - f" ORDER BY COUNT({column_name}) DESC" - ) self._comment = ( f"All the values{extra_comment} that appear in column {column_name}" f" of table {table_name}" ) self._annotation = None else: - self._query = ( - f"SELECT {column_name} AS value{extra_results} FROM" - f' (SELECT {column_name} FROM "{table_name}"' - f" WHERE {column_name} IS NOT NULL" - f" ORDER BY RANDOM() LIMIT {sample_count})" - f" AS _inner GROUP BY value ORDER BY COUNT({column_name}) DESC" - ) self._comment = ( f"The values{extra_comment} that appear in column {column_name}" f" of a random sample of {sample_count} rows of table {table_name}" @@ -101,26 +165,12 @@ def __init__( self._annotation = "sampled" else: if sample_count is None: - self._query = ( - f"SELECT value{extra_expo} FROM" - f" (SELECT {column_name} AS value, COUNT({column_name}) AS count" - f' FROM "{table_name}" WHERE {column_name} IS NOT NULL' - f" GROUP BY value ORDER BY count DESC) AS _inner" - f" WHERE {suppress_count} < count" - ) self._comment = ( f"All the values{extra_comment} that appear in column {column_name}" f" of table {table_name} more than {suppress_count} times" ) self._annotation = "suppressed" else: - self._query = ( - f"SELECT value{extra_expo} FROM (SELECT value, COUNT(value) AS count FROM" - f' (SELECT {column_name} AS value FROM "{table_name}"' - f" WHERE {column_name} IS NOT NULL ORDER BY RANDOM() LIMIT {sample_count})" - f" AS _inner GROUP BY value ORDER BY count DESC)" - f" AS _inner WHERE {suppress_count} < count" - ) self._comment = ( f"The values{extra_comment} that appear more than {suppress_count} times" f" in column {column_name}, out of a random sample of {sample_count} rows" @@ -293,7 +343,7 @@ class ChoiceProposerFactory(ProposerFactory): SAMPLE_COUNT = MAXIMUM_CHOICES SUPPRESS_COUNT = 7 - def get_proposers( + def get_proposers( # pylint: disable=too-many-locals self, columns: list[Column], engine: Engine ) -> Sequence[Proposer]: """Get the generators appropriate to these columns.""" @@ -302,27 +352,51 @@ def get_proposers( column = columns[0] column_name = column.name table_name = column.table.name + table_sql = schema_qualified_name(table_name, engine) + src_table = column.table + dialect = engine.dialect + col = literal_column(f'"{column_name}"') + src_table = column.table # preserves schema for schema-qualified databases generators = [] with engine.connect() as connection: - results = connection.execute( - text( - f'SELECT "{column_name}" AS v, COUNT("{column_name}")' - f' AS f FROM "{table_name}" GROUP BY v' - f" ORDER BY f DESC LIMIT {MAXIMUM_CHOICES + 1}" + stmt_count = ( + select( + col.label("v"), + func.count(col).label("f"), # pylint: disable=E1102 ) + .select_from(src_table) + .group_by(col) + .order_by(desc(func.count(col))) # pylint: disable=E1102 + .limit(MAXIMUM_CHOICES + 1) ) + results = connection.execute(stmt_count) if results is not None and results.rowcount <= MAXIMUM_CHOICES: vg = ValueGatherer(results, self.SUPPRESS_COUNT) if vg.counts: generators += [ ZipfChoiceProposer( - table_name, column_name, vg.values, vg.counts + table_name, + column_name, + vg.values, + vg.counts, + dialect=dialect, + table_sql=table_sql, ), UniformChoiceProposer( - table_name, column_name, vg.values, vg.counts + table_name, + column_name, + vg.values, + vg.counts, + dialect=dialect, + table_sql=table_sql, ), WeightedChoiceProposer( - table_name, column_name, vg.cvs, vg.counts + table_name, + column_name, + vg.cvs, + vg.counts, + dialect=dialect, + table_sql=table_sql, ), ] if vg.counts_not_suppressed: @@ -333,6 +407,8 @@ def get_proposers( vg.values_not_suppressed, vg.counts_not_suppressed, suppress_count=self.SUPPRESS_COUNT, + dialect=dialect, + table_sql=table_sql, ), UniformChoiceProposer( table_name, @@ -340,6 +416,8 @@ def get_proposers( vg.values_not_suppressed, vg.counts_not_suppressed, suppress_count=self.SUPPRESS_COUNT, + dialect=dialect, + table_sql=table_sql, ), WeightedChoiceProposer( table_name=table_name, @@ -347,16 +425,26 @@ def get_proposers( values=vg.cvs_not_suppressed, counts=vg.counts_not_suppressed, suppress_count=self.SUPPRESS_COUNT, + dialect=dialect, + table_sql=table_sql, ), ] - sampled_results = connection.execute( - text( - f"SELECT v, COUNT(v) AS f FROM" - f' (SELECT "{column_name}" as v FROM "{table_name}"' - f" ORDER BY RANDOM() LIMIT {self.SAMPLE_COUNT})" - f" AS _inner GROUP BY v ORDER BY f DESC" - ) + inner = ( + select(col.label("v")) + .select_from(src_table) + .order_by(Random()) + .limit(self.SAMPLE_COUNT) + .subquery("_inner") + ) + stmt_sample = ( + select( + inner.c.v, func.count(inner.c.v).label("f") # pylint: disable=E1102 + ) # pylint: disable=E1102 + .select_from(inner) + .group_by(inner.c.v) + .order_by(desc(func.count(inner.c.v))) # pylint: disable=E1102 ) + sampled_results = connection.execute(stmt_sample) if sampled_results is not None: vg = ValueGatherer(sampled_results, self.SUPPRESS_COUNT) if vg.counts: @@ -367,6 +455,8 @@ def get_proposers( vg.values, vg.counts, sample_count=self.SAMPLE_COUNT, + dialect=dialect, + table_sql=table_sql, ), UniformChoiceProposer( table_name, @@ -374,6 +464,8 @@ def get_proposers( vg.values, vg.counts, sample_count=self.SAMPLE_COUNT, + dialect=dialect, + table_sql=table_sql, ), WeightedChoiceProposer( table_name, @@ -381,6 +473,8 @@ def get_proposers( vg.cvs, vg.counts, sample_count=self.SAMPLE_COUNT, + dialect=dialect, + table_sql=table_sql, ), ] if vg.counts_not_suppressed: @@ -392,6 +486,8 @@ def get_proposers( vg.counts_not_suppressed, sample_count=self.SAMPLE_COUNT, suppress_count=self.SUPPRESS_COUNT, + dialect=dialect, + table_sql=table_sql, ), UniformChoiceProposer( table_name, @@ -400,6 +496,8 @@ def get_proposers( vg.counts_not_suppressed, sample_count=self.SAMPLE_COUNT, suppress_count=self.SUPPRESS_COUNT, + dialect=dialect, + table_sql=table_sql, ), WeightedChoiceProposer( table_name=table_name, @@ -408,6 +506,8 @@ def get_proposers( counts=vg.counts_not_suppressed, sample_count=self.SAMPLE_COUNT, suppress_count=self.SUPPRESS_COUNT, + dialect=dialect, + table_sql=table_sql, ), ] return generators diff --git a/datafaker/proposers/continuous.py b/datafaker/proposers/continuous.py index 056f6c6a..a7828152 100644 --- a/datafaker/proposers/continuous.py +++ b/datafaker/proposers/continuous.py @@ -5,11 +5,25 @@ from collections.abc import Iterable, Mapping, Sequence from typing import Any -from sqlalchemy import Column, Engine, RowMapping, text +from sqlalchemy import ( + Column, + Dialect, + Engine, + RowMapping, + Select, + Table, + case, + func, + literal, + null, + select, +) from sqlalchemy.exc import SQLAlchemyError +from sqlalchemy.sql.functions import coalesce from sqlalchemy.types import Integer, Numeric from typing_extensions import Self +from datafaker.dialects import IsNotNull, NullIf, Random, StdDev from datafaker.proposers.base import ( Buckets, NumericType, @@ -26,23 +40,30 @@ class ContinuousDistributionProposer(Proposer): expected_buckets: Sequence[NumericType] = [] - def __init__(self, table_name: str, column_name: str, buckets: Buckets): + def __init__( + self, + table: Table, + column: Column, + buckets: Buckets, + dialect: Dialect, + ): """Initialise a ContinuousDistributionProposer.""" super().__init__() - self.table_name = table_name - self.column_name = column_name + self.table = table + self.column = column self.buckets = buckets + self._dialect = dialect def nominal_kwargs(self) -> dict[str, Any]: """Get the arguments to be entered into ``config.yaml``.""" return { "mean": ( - f'SRC_STATS["auto__{self.table_name}"]["results"]' - f'[0]["mean__{self.column_name}"]' + f'SRC_STATS["auto__{self.table.name}"]["results"]' + f'[0]["mean__{self.column.name}"]' ), "sd": ( - f'SRC_STATS["auto__{self.table_name}"]["results"]' - f'[0]["stddev__{self.column_name}"]' + f'SRC_STATS["auto__{self.table.name}"]["results"]' + f'[0]["stddev__{self.column.name}"]' ), } @@ -58,15 +79,21 @@ def actual_kwargs(self) -> dict[str, Any]: def select_aggregate_clauses(self) -> dict[str, dict[str, str]]: """Get the query fragments the generators need to call.""" clauses = super().select_aggregate_clauses() + sd = StdDev(self.column).compile( + dialect=self._dialect, compile_kwargs={"literal_binds": True} + ) + mean = func.avg(self.column).compile( + dialect=self._dialect, compile_kwargs={"literal_binds": True} + ) return { **clauses, - f"mean__{self.column_name}": { - "clause": f"AVG({self.column_name})", - "comment": f"Mean of {self.column_name} from table {self.table_name}", + f"mean__{self.column.name}": { + "clause": str(mean), + "comment": f"Mean of {self.column.name} from table {self.table.name}", }, - f"stddev__{self.column_name}": { - "clause": f"STDDEV({self.column_name})", - "comment": f"Standard deviation of {self.column_name} from table {self.table_name}", + f"stddev__{self.column.name}": { + "clause": str(sd), + "comment": f"Standard deviation of {self.column.name} from table {self.table.name}", }, } @@ -138,14 +165,15 @@ class ContinuousDistributionProposerFactory(ProposerFactory): def _get_generators_from_buckets( self, - engine: Engine, # pylint: disable=unused-argument - table_name: str, - column_name: str, + engine: Engine, + src_table: Table, + column: Column, buckets: Buckets, ) -> Sequence[Proposer]: + dialect = engine.dialect return [ - GaussianProposer(table_name, column_name, buckets), - UniformProposer(table_name, column_name, buckets), + GaussianProposer(src_table, column, buckets, dialect=dialect), + UniformProposer(src_table, column, buckets, dialect=dialect), ] def get_proposers( @@ -162,9 +190,7 @@ def get_proposers( buckets = Buckets.make_buckets(engine, table, column) if buckets is None: return [] - return self._get_generators_from_buckets( - engine, table.name, column.name, buckets - ) + return self._get_generators_from_buckets(engine, table, column, buckets) class LogNormalProposer(Proposer): @@ -192,19 +218,21 @@ class LogNormalProposer(Proposer): # pylint: disable=too-many-arguments too-many-positional-arguments def __init__( self, - table_name: str, - column_name: str, + table: Table, + column: Column, buckets: Buckets, logmean: float, logstddev: float, + dialect: Dialect, ): """Initialise a LogNormalProposer.""" super().__init__() - self.table_name = table_name - self.column_name = column_name + self.table = table + self.column = column self.buckets = buckets self.logmean = logmean self.logstddev = logstddev + self._dialect = dialect def function_name(self) -> str: """Get the name of the generator function to call.""" @@ -218,12 +246,12 @@ def nominal_kwargs(self) -> dict[str, Any]: """Get the arguments to be entered into ``config.yaml``.""" return { "logmean": ( - f'SRC_STATS["auto__{self.table_name}"]["results"][0]' - f'["logmean__{self.column_name}"]' + f'SRC_STATS["auto__{self.table.name}"]["results"][0]' + f'["logmean__{self.column.name}"]' ), "logsd": ( - f'SRC_STATS["auto__{self.table_name}"]["results"][0]' - f'["logstddev__{self.column_name}"]' + f'SRC_STATS["auto__{self.table.name}"]["results"][0]' + f'["logstddev__{self.column.name}"]' ), } @@ -239,21 +267,22 @@ def select_aggregate_clauses(self) -> dict[str, dict[str, str]]: clauses = super().select_aggregate_clauses() return { **clauses, - f"logmean__{self.column_name}": { + f"logmean__{self.column.name}": { "clause": ( - f"AVG(CASE WHEN 0<{self.column_name} THEN LN({self.column_name})" + f"AVG(CASE WHEN 0<{self.column.name} THEN LN({self.column.name})" " ELSE NULL END)" ), - "comment": f"Mean of logs of {self.column_name} from table {self.table_name}", + "comment": f"Mean of logs of {self.column.name} from table {self.table.name}", }, - f"logstddev__{self.column_name}": { + f"logstddev__{self.column.name}": { "clause": ( - f"STDDEV(CASE WHEN 0<{self.column_name}" - f" THEN LN({self.column_name}) ELSE NULL END)" + f"{'STDEVP' if self._dialect.name == 'mssql' else 'STDDEV'}" + f"(CASE WHEN 0<{self.column.name}" + f" THEN LN({self.column.name}) ELSE NULL END)" ), "comment": ( - f"Standard deviation of logs of {self.column_name}" - f" from table {self.table_name}" + f"Standard deviation of logs of {self.column.name}" + f" from table {self.table.name}" ), }, } @@ -271,28 +300,30 @@ class ContinuousLogDistributionProposerFactory(ContinuousDistributionProposerFac def _get_generators_from_buckets( self, engine: Engine, - table_name: str, - column_name: str, + src_table: Table, + column: Column, buckets: Buckets, ) -> Sequence[Proposer]: + col = case( + (column > 0, func.log(column)), + else_=null(), + ) + stmt = select( + func.avg(col).label("logmean"), + func.stddev_samp(col).label("logstddev"), + ).select_from(src_table) with engine.connect() as connection: - result = connection.execute( - text( - f"SELECT AVG(CASE WHEN 0<{column_name} THEN LN({column_name})" - " ELSE NULL END) AS logmean," - f" STDDEV(CASE WHEN 0<{column_name} THEN LN({column_name}) ELSE NULL END)" - f' AS logstddev FROM "{table_name}"' - ) - ).first() + result = connection.execute(stmt).first() if result is None or result.logstddev is None: return [] return [ LogNormalProposer( - table_name, - column_name, + src_table, + column, buckets, float(result.logmean), float(result.logstddev), + dialect=engine.dialect, ) ] @@ -303,15 +334,17 @@ class MultivariateNormalProposer(Proposer): # pylint: disable=too-many-arguments too-many-positional-arguments def __init__( self, - table_name: str, - column_names: list[str], - query: str, + dialect: Dialect, + table: Table, + columns: list[Column], + query: Any, covariates: RowMapping, function_name: str, ) -> None: """Initialise a MultivariateNormalProposer.""" - self._table = table_name - self._columns = column_names + self._dialect = dialect + self._table = table + self._columns = columns self._query = query self._covariates = covariates self._function_name = function_name @@ -328,14 +361,19 @@ def nominal_kwargs(self) -> dict[str, Any]: def custom_queries(self) -> dict[str, Any]: """Get the queries the generators need to call.""" - cols = ", ".join(self._columns) + cols = ", ".join([c.name for c in self._columns]) return { f"auto__cov__{self._table}": { "comments": [ f"Means and covariate matrix for the columns {cols}," " so that we can produce the relatedness between these in the fake data." ], - "query": self._query, + "query": str( + self._query.compile( + dialect=self._dialect, + compile_kwargs={"literal_binds": True}, + ) + ), } } @@ -359,12 +397,12 @@ class MultivariateNormalGeneratorFactoryBase(ProposerFactory): """Generator factory that makes distributions and maybe partitions.""" @abstractmethod - def query_predicate(self, column: Column) -> str: - """Get the SQL expression for whether this column should be queried.""" + def query_predicate(self, column: Column) -> Any: + """Get the SQLAlchemy expression for whether this column should be queried.""" @abstractmethod - def query_var(self, column: str) -> str: - """Get the SQL expression of the value to query for this column.""" + def query_var(self, column: Column) -> Any: + """Get the SQLAlchemy expression of the value to query for this column.""" @abstractmethod def query_comment(self) -> str: @@ -375,14 +413,14 @@ def query_comment(self) -> str: which will be a string like ``apples, pears and bananas``. """ - def get_named_tables(self) -> Mapping[str, str]: + def get_named_tables(self) -> Mapping[str, Column]: """ Get a mapping showing which tables have naming columns. A naming column is a column that provides a nice name for the row. We could call tables containing such a column as a "named table". - :return: A map mapping names of named tables to the names of their - naming columns. + :return: A map mapping names of named tables to their naming + columns. """ return {} @@ -393,7 +431,7 @@ class CovariateQuery: def __init__( self, - table: str, + table: Table, factory: MultivariateNormalGeneratorFactoryBase, ) -> None: """ @@ -402,11 +440,11 @@ def __init__( :param table: The name of the table to be queried. :param factory: The generator factory, perhaps with overridden ``query_var`` and ``query_predicate`` methods. + :param dialect: The SQLAlchemy dialect name (e.g. ``mssql.dialect()``). """ - self.table = table + self.table: Table = table self._columns: Sequence[Column] = [] - self._predicates: Iterable[str] = [] - self._group_by_clause = "" + self._predicates: Iterable[Any] = [] self._constant_clauses: dict[int, Column] = {} self.suppress_count = 1 self._sample_count: int | None = None @@ -454,7 +492,7 @@ def sample_count(self, count: int) -> Self: self._sample_count = count return self - def predicates(self, predicates: Iterable[str]) -> Self: + def predicates(self, predicates: Iterable[Any]) -> Self: """ Set the predicates to filter the queried table by. @@ -463,15 +501,6 @@ def predicates(self, predicates: Iterable[str]) -> Self: self._predicates = predicates return self - def group_by(self, clause: str) -> Self: - """ - Set the `GROUP BY` clause to the query for this partition. - - :param group_by_clause: Any GROUP BY clause to the query getting the partition. - """ - self._group_by_clause = clause - return self - def constant_clauses(self, clauses: dict[int, Column]) -> Self: """ Set constant clauses. @@ -485,18 +514,19 @@ def constant_clauses(self, clauses: dict[int, Column]) -> Self: return self def _get_constants_and_joins( - self, named_tables: Mapping[str, str] - ) -> tuple[str, str]: + self, named_tables: Mapping[str, Column], subquery: Any + ) -> tuple[list[Column], list[Table]]: """ Extra JOINs to give names to foreign keys. This enables information governance people can understand the results better. :param named_tables: A mapping of tables that have names to columns that supply those names. - :return: A pair of strings; one is constants in the SELECT clause, the second is - JOIN clauses to join tables to the outer query in order to make names appear + :return: A pair; the first is constants in the SELECT clause, the second is + tables to join to the outer query in order to make names appear in the output. """ + # Column names -> Foreign Keys to named_tables col_to_named_fks = { col.name: [ fk.column @@ -505,89 +535,98 @@ def _get_constants_and_joins( ] for col in self._constant_clauses.values() } + # Column names -> single FK to named_tables col_to_named_fk = {col: fks[0] for col, fks in col_to_named_fks.items() if fks} - name_joins = "" - constants = "" + name_joins: list[Table] = [] + constants: list[Any] = [] for index, col in self._constant_clauses.items(): col_name = col.name - constants += f", _q.{col_name} AS k{index}" + constants.append(subquery.c[f"k{index}"]) if col_name in col_to_named_fk: fk_target = col_to_named_fk[col_name] - fk_target_table = fk_target.table.name - name_joins += ( - f" JOIN {fk_target_table} AS _j{index}" - f" ON _q.{col_name}=_j{index}.{fk_target.name}" - ) - constants += ( - f", _j{index}.{named_tables[fk_target_table]}" - f" AS k{index}_{col_name}__name" + name_joins.append(fk_target.table) + constants.append( + named_tables[fk_target.table.name].label( + f"k{index}_{col_name}__name" + ) ) - return name_joins, constants + return constants, name_joins - def get(self) -> str: + def get(self) -> Any: """ Get the SQL query. - :return: The SQL query for this partition. + :return: The SQLAlchemy query for this partition. """ - means = "".join(f", _q.m{i}" for i in range(len(self._columns))) - covs = "".join( + middle = self._middle_query(self._inner_query()).subquery("_q") + means = [middle.c[f"m{i}"] for i in range(len(self._columns))] + covs = [ ( - f", (_q.s{ix}_{iy} - _q.count * _q.m{ix} * _q.m{iy})" - f"/NULLIF(_q.count - 1, 0) AS c{ix}_{iy}" - ) + ( + middle.c[f"s{ix}_{iy}"] + - middle.c["count"] * middle.c[f"m{ix}"] * middle.c[f"m{iy}"] + ) + / NullIf(middle.c["count"] - 1, literal(0)) + ).label(f"c{ix}_{iy}") for iy in range(len(self._columns)) for ix in range(iy + 1) - ) - subquery = self._inner_query() - # if there are any numeric columns we need at least - # two rows to make any (co)variances at all - suppress_clause = ( - f" WHERE {self.suppress_count} < _q.count" if self._columns else "" - ) + ] rank = len(self._columns) named_tables = self._factory.get_named_tables() - name_joins, constants = self._get_constants_and_joins(named_tables) - return ( - f"SELECT {rank} AS rank{constants}, _q.count AS count{means}{covs}" - f" FROM ({self._middle_query(subquery)})" - f" AS _q{name_joins}{suppress_clause}" - ) + constants, name_joins = self._get_constants_and_joins(named_tables, middle) + query = select( + literal(rank).label("rank"), middle.c["count"], *constants, *means, *covs + ).select_from(middle) + for j in name_joins: + query = query.join(j) + # if there are any numeric columns we need at least + # two rows to make any (co)variances at all + if self._columns: + query = query.where(middle.c["count"] > self.suppress_count) + return query - def _inner_query(self) -> str: + def _inner_query(self) -> Select: """Get the rows from the table that we are interested in.""" + constants = [col.label(f"k{i}") for i, col in self._constant_clauses.items()] + values = [col.label(f"v{i}") for i, col in enumerate(self._columns)] + sel = select(*constants, *values).select_from(self.table) preds = itertools.chain( (self._factory.query_predicate(col) for col in self._columns), self._predicates, ) - where = " AND ".join(preds) if preds else "" - if where: - where = " WHERE " + where - if self._sample_count is None: - return f'"{self.table}"{where}' - return ( - f'(SELECT * FROM "{self.table}"{where} ORDER BY RANDOM()' - f" LIMIT {self._sample_count}) AS _sampled" - ) + if preds: + sel = sel.filter(*preds) + if self._sample_count is not None: + sel = sel.order_by(Random()).limit(self._sample_count) + return sel - def _middle_query(self, inner_query: str) -> str: + def _middle_query(self, inner_query: Any) -> Any: """Get the basic statistics (and constants) from the inner query.""" - multiples = "".join( - ( - f", SUM({self._factory.query_var(colx.name)}" - f" * {self._factory.query_var(coly.name)}) AS s{ix}_{iy}" - ) - for iy, coly in enumerate(self._columns) - for ix, colx in enumerate(self._columns[: iy + 1]) - ) - avgs = "".join( - f", AVG({self._factory.query_var(col.name)}) AS m{i}" - for i, col in enumerate(self._columns) - ) - constants = "".join(", " + col.name for col in self._constant_clauses.values()) - return ( - f"SELECT COUNT(*) AS count{multiples}{avgs}{constants}" - f" FROM {inner_query}{self._group_by_clause}" + inner = inner_query.subquery("_sampled") + col_count = len(self._columns) + multiples = [ + func.sum( + self._factory.query_var(inner.c[f"v{ix}"]) + * self._factory.query_var(inner.c[f"v{iy}"]) + ).label(f"s{ix}_{iy}") + for iy in range(col_count) + for ix in range(iy + 1) + ] + avgs = [ + func.avg(self._factory.query_var(inner.c[f"v{i}"])).label(f"m{i}") + for i in range(col_count) + ] + constants = [inner.c[f"k{k}"] for k in self._constant_clauses.keys()] + query = select( + func.count().label("count"), # pylint: disable=not-callable + *multiples, + *avgs, + *constants, + ).select_from(inner) + if len(self._constant_clauses) == 0: + return query + return query.group_by( + *[inner.c[f"k{k}"] for k in self._constant_clauses.keys()] ) @@ -598,11 +637,11 @@ def function_name(self) -> str: """Get the name of the generator function to call.""" return "multivariate_normal" - def query_predicate(self, column: Column) -> str: - """Get the SQL expression for whether this column should be queried.""" - return column.name + " IS NOT NULL" + def query_predicate(self, column: Column) -> Any: + """Get the SQLAlchemy expression for whether this column should be queried.""" + return IsNotNull(column) - def query_var(self, column: str) -> str: + def query_var(self, column: Column) -> Any: """Get the SQL expression of the value to query for this column.""" return column @@ -625,13 +664,12 @@ def get_proposers( ct = get_column_type(c) if not isinstance(ct, Numeric) and not isinstance(ct, Integer): return [] - column_names = [c.name for c in columns] - table = columns[0].table.name + table = columns[0].table cq = CovariateQuery(table, self).columns(columns) query = cq.get() with engine.connect() as connection: try: - covariates = connection.execute(text(query)).mappings().first() + covariates = connection.execute(query).mappings().first() except SQLAlchemyError as e: logger.debug("SQL query %s failed with error %s", query, e) return [] @@ -639,8 +677,9 @@ def get_proposers( return [] return [ MultivariateNormalProposer( + connection.dialect, table, - column_names, + columns, query, covariates, self.function_name(), @@ -655,13 +694,13 @@ def function_name(self) -> str: """Get the name of the generator function to call.""" return "multivariate_lognormal" - def query_predicate(self, column: Column) -> str: - """Get the SQL expression for whether this column should be queried.""" - return f"COALESCE(0 < {column.name}, FALSE)" + def query_predicate(self, column: Column) -> Any: + """Get the SQLAlchemy expression for whether this column should be queried.""" + return coalesce(column > 0, False) - def query_var(self, column: str) -> str: + def query_var(self, column: Column) -> Any: """Get the expression to query for, for this column.""" - return f"LN({column})" + return func.ln(column) def query_comment(self) -> str: """Return the human-readable comment for this generator.""" diff --git a/datafaker/proposers/intervals.py b/datafaker/proposers/intervals.py index 44727678..17393cf5 100644 --- a/datafaker/proposers/intervals.py +++ b/datafaker/proposers/intervals.py @@ -3,58 +3,17 @@ from collections.abc import Mapping, Sequence from typing import Any -from sqlalchemy import Column, Engine, ForeignKey, MetaData, dialects, func, select -from sqlalchemy.ext.compiler import compiles -from sqlalchemy.sql.elements import ColumnElement -from sqlalchemy.sql.visitors import InternalTraversal +from sqlalchemy import Column, Dialect, Engine, ForeignKey, MetaData, func, select from sqlalchemy.types import Date, DateTime -from datafaker.db_utils import get_dialect +from datafaker.dialects import SecondsDifference, StdDev from datafaker.proposers.base import Buckets, Proposer, ProposerFactory, get_column_type from datafaker.providers import AnchoredProvider -from datafaker.settings import get_settings from datafaker.utils import get_property RelatedColumn = tuple[ForeignKey | None, Column] -class SecondsDifference(ColumnElement[int]): # pylint: disable=too-many-ancestors - """Represent getting the difference between times in seconds.""" - - expr1: ColumnElement[Date | DateTime] - expr2: ColumnElement[Date | DateTime] - - _traverse_internals = [ - ("expr1", InternalTraversal.dp_clauseelement), - ("expr2", InternalTraversal.dp_clauseelement), - ] - - def __init__( - self, - expr1: ColumnElement[Date | DateTime], - expr2: ColumnElement[Date | DateTime], - ): - """ - Get a clause for the number of seconds between two times. - - The interval is from ``expr2`` to ``expr1``. - """ - self.expr1 = expr1 - self.expr2 = expr2 - - __sa_operate__ = ColumnElement.operate - - -@compiles(SecondsDifference) -def compile_seconds_difference( - element: SecondsDifference, compiler: Any, **kw: Any -) -> str: - """Create SQL for the difference between two datetimes in seconds.""" - e1 = compiler.process(element.expr1, **kw) - e2 = compiler.process(element.expr2, **kw) - return f"CAST(EXTRACT(EPOCH FROM ({e1})) - EXTRACT(EPOCH FROM ({e2})) AS FLOAT)" - - def _set_roles_for_column( out: dict[str, list[RelatedColumn]], fk: ForeignKey | None, @@ -131,6 +90,7 @@ def __init__( mean: float, column: Column, anchor: Column, + dialect: Dialect, buckets: Buckets | None = None, ): """ @@ -144,6 +104,7 @@ def __init__( self._mean = mean self._anchor = anchor self._column = column + self._dialect = dialect self._provider = AnchoredProvider(metadata=metadata) if buckets is None: self._fit = None @@ -195,17 +156,16 @@ def select_aggregate_clauses(self) -> dict[str, dict[str, str]]: This will only work for anchors in the same table. """ - dest_dsn = get_settings().dst_dsn - if dest_dsn: - dialect = get_dialect(dest_dsn) - else: - dialect = dialects.postgresql.dialect() # type: ignore mean_q = func.avg(SecondsDifference(self._column, self._anchor)) - sd_q = func.stddev(SecondsDifference(self._column, self._anchor)) + sd_q = StdDev(SecondsDifference(self._column, self._anchor)) return { f"mean__{self._column.name}": { - "clause": str(mean_q.compile(dialect=dialect)), + "clause": str( + mean_q.compile( + dialect=self._dialect, compile_kwargs={"literal_binds": True} + ) + ), "comment": ( "Mean of interval between " + self._anchor.name @@ -216,7 +176,11 @@ def select_aggregate_clauses(self) -> dict[str, dict[str, str]]: ), }, f"stddev__{self._column.name}": { - "clause": str(sd_q.compile(dialect=dialect)), + "clause": str( + sd_q.compile( + dialect=self._dialect, compile_kwargs={"literal_binds": True} + ) + ), "comment": ( "Standard deviation of interval between " + self._anchor.name @@ -258,7 +222,7 @@ def make_date_after_proposers( result = connection.execute( select( func.avg(SecondsDifference(column, anchor)).label("mean"), - func.stddev(SecondsDifference(column, anchor)).label("sd"), + StdDev(SecondsDifference(column, anchor)).label("sd"), ).select_from(column.table) ).first() if result is None or result.sd is None: @@ -273,7 +237,8 @@ def make_date_after_proposers( result.mean, column, anchor, - buckets, + dialect=engine.dialect, + buckets=buckets, ) ] diff --git a/datafaker/proposers/mimesis.py b/datafaker/proposers/mimesis.py index e14b042c..451ad792 100644 --- a/datafaker/proposers/mimesis.py +++ b/datafaker/proposers/mimesis.py @@ -5,7 +5,7 @@ import mimesis import mimesis.locales -from sqlalchemy import Column, Engine, func, text +from sqlalchemy import Column, Engine, cast, extract, func, literal_column, select from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.types import Date, DateTime, Integer, Numeric, String, Time @@ -187,17 +187,24 @@ def make_singleton( cls, column: Column, engine: Engine, function_name: str ) -> Sequence[Proposer]: """Make the appropriate generation configuration for this column.""" - extract_year = f"CAST(EXTRACT(YEAR FROM {column.name}) AS INT)" - max_year = f"MAX({extract_year})" - min_year = f"MIN({extract_year})" + col_expr = literal_column(column.name) + year_expr = cast(extract("year", col_expr), Integer()) + min_expr = func.min(year_expr) # pylint: disable=E1111 + max_expr = func.max(year_expr) # pylint: disable=E1111 + stmt = select(min_expr.label("start"), max_expr.label("end")).select_from( + column.table + ) with engine.connect() as connection: - result = connection.execute( - text( - f'SELECT {min_year} AS start, {max_year} AS end FROM "{column.table.name}"' - ) - ).first() + result = connection.execute(stmt).first() if result is None or result.start is None or result.end is None: return [] + dialect = engine.dialect + min_year = str( + min_expr.compile(dialect=dialect, compile_kwargs={"literal_binds": True}) + ) + max_year = str( + max_expr.compile(dialect=dialect, compile_kwargs={"literal_binds": True}) + ) return [ MimesisDateTimeProposer( column, diff --git a/datafaker/proposers/partitioned.py b/datafaker/proposers/partitioned.py index 8d6eec05..660c9175 100644 --- a/datafaker/proposers/partitioned.py +++ b/datafaker/proposers/partitioned.py @@ -6,10 +6,24 @@ from typing import Any, Union import sqlalchemy -from sqlalchemy import Column, Connection, Engine, RowMapping, text +from sqlalchemy import ( + Column, + Connection, + Dialect, + Engine, + MetaData, + RowMapping, + Table, + case, + func, + select, + text, +) from sqlalchemy.exc import DatabaseError +from sqlalchemy.sql.functions import coalesce from sqlalchemy.types import Integer, Numeric +from datafaker.dialects import IsNotNull, IsNull from datafaker.proposers.base import Proposer, dist_gen, get_column_type from datafaker.proposers.continuous import ( CovariateQuery, @@ -156,7 +170,7 @@ class PartitionCountQuery: def __init__( self, connection: Connection, - query: str, + query: Any, nullable_columns: Iterable[NullableColumn], overall_comment: str, ) -> None: @@ -164,12 +178,12 @@ def __init__( Initialise the partition count query. :param connection: Database connection. - :param query: The query getting the row counts of the null pattern partitions. + :param query: The SQLAlchemy query getting the row counts of the null pattern partitions. :param table_name: The name of the table being queried. :param nullable_columns: The columns that are being checked for nullness. """ self.query = query - rows = connection.execute(text(query)).mappings().fetchall() + rows = connection.execute(query).mappings().fetchall() self.results = [dict(row) for row in rows] self.comments = [ overall_comment, @@ -202,6 +216,7 @@ class NullPartitionedNormalProposer(Proposer): # pylint: disable=too-many-arguments too-many-positional-arguments def __init__( self, + dialect: Dialect, query_name: str, partitions: dict[int, RowPartition], function_name: str = "grouped_multivariate_lognormal", @@ -209,6 +224,7 @@ def __init__( partition_count_query: PartitionCountQuery | None = None, ): """Initialise a NullPartitionedNormalGenerator.""" + self._dialect = dialect self._query_name = query_name self._partitions = partitions self._function_name = function_name @@ -283,10 +299,13 @@ def custom_queries(self) -> dict[str, Any]: } if not self._partition_count_query: return partitions + pc_query = self._partition_count_query.query.compile( + dialect=self._dialect, compile_kwargs={"literal_binds": True} + ) return { self._count_query_name(): { "comments": self._partition_count_query.comments, - "query": self._partition_count_query.query, + "query": str(pc_query), }, **partitions, } @@ -367,10 +386,9 @@ def __init__( nonnull_columns = {nc.column.name for nc in partition_nonnulls} self.included_numeric: list[Column] = [] self.included_choice: dict[int, str] = {} - self.group_by_clause = "" self.constant_clauses: dict[int, Column] = {} self.excluded: dict[str, str] = {} - self.predicates: list[str] = [] + self.predicates: list[Any] = [] self.nones: dict[int, None] = {} for col_index, column in enumerate(columns): col_name = column.name @@ -380,15 +398,11 @@ def __init__( else: index = len(self.included_numeric) + len(self.included_choice) self.included_choice[index] = col_name - if self.group_by_clause: - self.group_by_clause += ", " + col_name - else: - self.group_by_clause = " GROUP BY " + col_name self.constant_clauses[index] = column - self.predicates.append(f"{col_name} IS NOT NULL") + self.predicates.append(IsNotNull(column)) else: self.excluded[col_name] = f"{col_name} IS NULL" - self.predicates.append(f"{col_name} IS NULL") + self.predicates.append(IsNull(column)) self.nones[col_index] = None @@ -410,14 +424,14 @@ def function_name(self) -> str: """Get the name of the generator function to call.""" return "grouped_multivariate_normal" - def query_predicate(self, column: Column) -> str: - """Get a SQL expression that is true when ``column`` is available for analysis.""" + def query_predicate(self, column: Column) -> Any: + """Get a SQLAlchemy expression that is true when ``column`` is available for analysis.""" if is_numeric(column): # x <> x + 1 ensures that x is not infinity or NaN - return f"COALESCE({column.name} <> {column.name} + 1, FALSE)" - return f"{column.name} IS NOT NULL" + return coalesce(column != column + 1, False) + return IsNotNull(column) - def query_var(self, column: str) -> str: + def query_var(self, column: Column) -> Any: """Return the expression we are querying for in this column.""" return column @@ -433,24 +447,41 @@ def query_comment(self) -> str: " that covers the columns {columns}." ) - def get_named_tables(self) -> Mapping[str, str]: + def get_named_tables(self) -> Mapping[str, Column]: """ Get a mapping showing which tables have naming columns. Based on the configuration file. - :return: A map mapping names of named tables to the names of their - naming columns. + :return: A map mapping names of named tables to their naming + columns. """ return self._named_tables - def __init__(self, config: Mapping[str, Any]) -> None: + def __init__(self, config: Mapping[str, Any], metadata: MetaData) -> None: """Initialize the null partitioned generator factory.""" tables: dict[str, Any] = get_property(config, "tables", {}) - self._named_tables = { - table_name: table_conf["name_column"] + named_tables: list[tuple[str, str]] = [ + (table_name, table_conf["name_column"]) for table_name, table_conf in tables.items() if isinstance(table_conf, Mapping) and "name_column" in table_conf + ] + delkeys: set[str] = set() + for table_name, column_name in named_tables: + if table_name not in metadata.tables: + logger.warning("Configured table %s not present in database.") + delkeys.add(table_name) + elif column_name not in metadata.tables[table_name].columns: + logger.warning( + "name_column %s configured in table %s is not a column in this table.", + column_name, + table_name, + ) + delkeys.add(table_name) + self._named_tables = { + t: metadata.tables[t].columns[c] + for t, c in named_tables + if t not in delkeys } def get_nullable_columns(self, columns: list[Column]) -> list[NullableColumn]: @@ -466,30 +497,38 @@ def get_nullable_columns(self, columns: list[Column]) -> list[NullableColumn]: ) return out + def _get_query_predicate(self, nc: NullableColumn) -> Any: + return case( + (self.query_predicate(nc.column), nc.bitmask), + else_=0, + ) + def get_partition_count_query( - self, ncs: list[NullableColumn], table: str, where: str | None = None - ) -> str: + self, + ncs: list[NullableColumn], + table: Table, + suppress_count: int = 0, + ) -> Any: """ - Get a SQL expression returning columns ``count`` and ``index``. + Get a SQLAlchemy expression returning columns ``count`` and ``index``. Each row returned represents one of the null pattern partitions. ``index`` is the bitmask of all those nullable columns that are not null for this partition, and ``count`` is the total number of rows in this partition. """ - index_exp = " + ".join( - f"CASE WHEN {self.query_predicate(nc.column)} THEN {nc.bitmask} ELSE 0 END" - for nc in ncs - ) - if where is None: - return ( - f'SELECT COUNT(*) AS count, {index_exp} AS "index" FROM "{table}"' - ' GROUP BY "index"' + index_exp = sum(self._get_query_predicate(nc) for nc in ncs) + sel = ( + select( + func.count().label("count"), # pylint: disable=not-callable + index_exp.label("index"), ) - return ( - 'SELECT count, "index" FROM (SELECT COUNT(*) AS count,' - f' {index_exp} AS "index"' - f' FROM "{table}" GROUP BY "index") AS _q {where}' + .select_from(table) + .group_by("index") ) + if 1 < suppress_count: + sb = sel.subquery("_q") + sel = select(sb.c["count", "index"]).where(sb.c["count"] > suppress_count) + return sel # pylint: disable=too-many-arguments too-many-positional-arguments def _get_generator( @@ -500,9 +539,6 @@ def _get_generator( nullable_columns: list[NullableColumn], name_suffix: str | None = None, ) -> NullPartitionedNormalProposer | None: - where = "" - if 1 < cov_query.suppress_count: - where = f' WHERE {cov_query.suppress_count} < "count"' partitions: dict[int, RowPartition] = {} for partition_nonnulls in powerset(nullable_columns): partition_def = NullPatternPartition(columns, partition_nonnulls) @@ -510,13 +546,16 @@ def _get_generator( partition_def.included_numeric, ).predicates( partition_def.predicates, - ).group_by( - partition_def.group_by_clause, ).constant_clauses( partition_def.constant_clauses, ) partitions[partition_def.index] = RowPartition( - query=cov_query.get(), + query=str( + cov_query.get().compile( + dialect=connection.dialect, + compile_kwargs={"literal_binds": True}, + ) + ), query_comment=cov_query.get_query_comment(), included_numeric=partition_def.included_numeric, included_choice=partition_def.included_choice, @@ -526,8 +565,13 @@ def _get_generator( ) if not self._execute_partition_queries(connection, partitions): return None - query = self.get_partition_count_query(nullable_columns, cov_query.table, where) + query = self.get_partition_count_query( + nullable_columns, + cov_query.table, + cov_query.suppress_count, + ) return NullPartitionedNormalProposer( + connection.dialect, f"{cov_query.table}__{columns[0].name}", partitions, self.function_name(), @@ -551,7 +595,7 @@ def get_proposers( nullable_columns = self.get_nullable_columns(columns) if not nullable_columns: return [] - table = columns[0].table.name + table = columns[0].table gens: list[Proposer | None] = [] try: with engine.connect() as connection: @@ -574,9 +618,10 @@ def get_proposers( name_suffix="sampled", ) ) - cov_query = CovariateQuery(table, self).set_suppress_count( - self.SUPPRESS_COUNT - ) + cov_query = CovariateQuery( + table, + self, + ).set_suppress_count(self.SUPPRESS_COUNT) gens.append( self._get_generator( connection, @@ -609,7 +654,7 @@ def _execute_partition_queries( """ Execute the query in each partition, filling in the covariates. - :return: True if all the partitions work, False if any of them fail. + :return: False if all the partitions fail, True if any of them work. """ found_nonzero = False for rp in partitions.values(): @@ -635,16 +680,16 @@ def function_name(self) -> str: """Get the name of the generator function to call.""" return "grouped_multivariate_lognormal" - def query_predicate(self, column: Column) -> str: + def query_predicate(self, column: Column) -> Any: """Get the SQL expression testing if the value in this column should be used.""" if is_numeric(column): # x <> x + 1 ensures that x is not infinity or NaN - return f"COALESCE({column.name} <> {column.name} + 1 AND 0 < {column.name}, FALSE)" - return f"{column.name} IS NOT NULL" + return coalesce(column != column + 1 and column > 0, False) + return IsNotNull(column) - def query_var(self, column: str) -> str: + def query_var(self, column: Column) -> Any: """Get the variable or expression we are querying for this column.""" - return f"LN({column})" + return func.ln(column) def query_comment(self) -> str: """Return the human-readable comment for this generator.""" diff --git a/datafaker/providers.py b/datafaker/providers.py index 57d83454..76c10541 100644 --- a/datafaker/providers.py +++ b/datafaker/providers.py @@ -10,8 +10,9 @@ from mimesis import Datetime, Text from mimesis.providers.base import BaseDataProvider, BaseProvider from sqlalchemy import Column, Connection, MetaData -from sqlalchemy.sql import func, functions, select +from sqlalchemy.sql import func, select +from datafaker.dialects import Random from datafaker.utils import T, logger @@ -28,7 +29,7 @@ def column_value( db_connection: Connection, orm_class: Any, column_name: str ) -> Any: """Return a random value from the column specified.""" - query = select(orm_class).order_by(functions.random()).limit(1) + query = select(orm_class).order_by(Random()).limit(1) random_row = db_connection.execute(query).first() if random_row: diff --git a/datafaker/remove.py b/datafaker/remove.py index 917c7843..0949e048 100644 --- a/datafaker/remove.py +++ b/datafaker/remove.py @@ -60,12 +60,13 @@ def remove_db_vocab( def remove_db_tables(metadata: Optional[MetaData]) -> None: """Drop the tables in the destination schema.""" + schema_name = get_destination_schema() dst_engine = get_sync_engine( create_db_engine( get_destination_dsn(), - schema_name=get_destination_schema(), + schema_name=schema_name, ) ) if metadata is None: - metadata = get_metadata(dst_engine) + metadata = get_metadata(dst_engine, schema_name=schema_name) metadata.drop_all(dst_engine) diff --git a/datafaker/serialize_metadata.py b/datafaker/serialize_metadata.py index e4e81792..6d043496 100644 --- a/datafaker/serialize_metadata.py +++ b/datafaker/serialize_metadata.py @@ -7,7 +7,7 @@ import parsy from sqlalchemy import Column, Dialect, Engine, ForeignKey, MetaData, Table -from sqlalchemy.dialects import oracle, postgresql +from sqlalchemy.dialects import mssql, oracle, postgresql from sqlalchemy.sql import schema, sqltypes from datafaker.db_utils import constraint_name @@ -16,6 +16,7 @@ get_property, make_foreign_key_name, split_column_full_name, + unqualify_fk_target, ) TableT = dict[str, typing.Any] @@ -74,7 +75,9 @@ def string_type(type_: type) -> ParserType: Make a parser for a SQL string type. Parses TYPE_NAME, TYPE_NAME(32), TYPE_NAME COLLATE "fr" - or TYPE_NAME(32) COLLATE "fr" + or TYPE_NAME(32) COLLATE "fr" (PostgreSQL style, quoted collation name) + or TYPE_NAME(32) COLLATE SQL_Latin1_General_CP1_CI_AS + (MS-SQL style, unquoted collation name) """ @generate(type_.__name__) @@ -84,15 +87,18 @@ def st_parser() -> typing.Generator[ParserType, None, typing.Any]: length: int | None = yield ( parsy.string("(") >> integer() << parsy.string(")") ).optional() - collation: str | None = yield ( - parsy.string(' COLLATE "') >> parsy.regex(r'[^"]*') << parsy.string('"') + collation: str | None = yield parsy.alt( + # PostgreSQL: COLLATE "name" (quoted) + parsy.string(' COLLATE "') >> parsy.regex(r'[^"]*') << parsy.string('"'), + # MS-SQL: COLLATE name (unquoted identifier) + parsy.string(" COLLATE ") >> parsy.regex(r"\S+"), ).optional() return type_(length=length, collation=collation) return st_parser -def time_type(type_: type, pg_type: type) -> ParserType: +def time_type(type_: type, tz_type: type) -> ParserType: """ Make a parser for a SQL date/time type. @@ -100,10 +106,10 @@ def time_type(type_: type, pg_type: type) -> ParserType: or TYPE_NAME(32) WITH TIME ZONE :param type_: The SQLAlchemy type we would like to parse. - :param pg_type: The PostgreSQL type we would like to parse if precision - or timezone is provided. + :param tz_type: The type to instantiate when precision or timezone is + provided (e.g. ``postgresql.types.TIMESTAMP``). :return: ``type_`` if neither precision nor timezone are provided in the - parsed text, ``pg_type(precision, timezone)`` otherwise. + parsed text, ``tz_type(precision, timezone)`` otherwise. """ @generate(type_.__name__) @@ -121,20 +127,37 @@ def pgt_parser() -> typing.Generator[ParserType, None, typing.Any]: if precision is None and not timezone: # normal sql type return type_ - return pg_type(precision=precision, timezone=timezone) + return tz_type(precision=precision, timezone=timezone) return pgt_parser +@parsy.generate("VARBINARY") # type: ignore +def _mssql_varbinary_parser() -> typing.Generator[ParserType, None, typing.Any]: + """Parse VARBINARY, VARBINARY(n), or VARBINARY(max/MAX).""" + yield parsy.string("VARBINARY") + length: int | None = yield ( + parsy.string("(") + >> ((parsy.string("max") | parsy.string("MAX")).result(None) | integer()) + << parsy.string(")") + ).optional() + return mssql.VARBINARY(length=length) + + SIMPLE_TYPE_PARSER = parsy.alt( parsy.string("DOUBLE PRECISION").result( sqltypes.DOUBLE_PRECISION ), # must be before DOUBLE - simple(sqltypes.FLOAT), + numeric_type(sqltypes.FLOAT), simple(sqltypes.DOUBLE), simple(sqltypes.INTEGER), simple(sqltypes.SMALLINT), simple(sqltypes.BIGINT), + # DATETIME2 and DATETIMEOFFSET must come before DATETIME — parsy.alt() is + # ordered and does not backtrack once a parser has consumed input, so the + # longer names must be tried first. + numeric_type(mssql.DATETIMEOFFSET), + numeric_type(mssql.DATETIME2), simple(sqltypes.DATETIME), simple(sqltypes.DATE), simple(sqltypes.CLOB), @@ -142,13 +165,40 @@ def pgt_parser() -> typing.Generator[ParserType, None, typing.Any]: simple(sqltypes.UUID), simple(sqltypes.BLOB), simple(sqltypes.BOOLEAN), - simple(postgresql.TSVECTOR), - simple(postgresql.BYTEA), - simple(postgresql.CIDR), + # PostgreSQL-specific types — mapped to cross-dialect equivalents so that + # an orm.yaml produced from a PostgreSQL source can be used with MS-SQL. + # PostgreSQL recreates these correctly; MSSQL gets a functional fallback. + parsy.string("TSVECTOR").result( + sqltypes.Text + ), # no MS-SQL equivalent; degrade to Text + parsy.string("BYTEA").result(sqltypes.LargeBinary), # MS-SQL: VARBINARY(MAX) + parsy.string("CIDR").result( + sqltypes.String(43) + ), # no MS-SQL equivalent; store as VARCHAR(43) + # PostgreSQL SERIAL pseudo-types — map to plain integers. datafaker does + # not rely on server-side autoincrement; the @compiles hook in dialects.py + # strips IDENTITY from MS-SQL DDL so explicit INSERTs work without + # SET IDENTITY_INSERT. BIGSERIAL/SMALLSERIAL listed before SERIAL so + # the common "SERIAL" prefix is tried last (defensive ordering). + parsy.string("BIGSERIAL").result(sqltypes.BIGINT), + parsy.string("SMALLSERIAL").result(sqltypes.SMALLINT), + parsy.string("SERIAL").result(sqltypes.INTEGER), numeric_type(sqltypes.NUMERIC), numeric_type(sqltypes.DECIMAL), numeric_type(postgresql.BIT), - numeric_type(postgresql.REAL), + numeric_type(sqltypes.REAL), # was postgresql.REAL; sqltypes.REAL is cross-dialect + # MS-SQL-specific types + simple(mssql.UNIQUEIDENTIFIER), + _mssql_varbinary_parser, + numeric_type(mssql.BINARY), + simple(mssql.MONEY), + simple(mssql.SMALLMONEY), + simple(mssql.IMAGE), + simple(mssql.TINYINT), + simple(mssql.SMALLDATETIME), + simple(mssql.NTEXT), + simple(mssql.SQL_VARIANT), + simple(mssql.ROWVERSION), string_type(sqltypes.CHAR), string_type(sqltypes.NCHAR), string_type(sqltypes.VARCHAR), @@ -206,6 +256,7 @@ def dict_to_column( col_name: str, rep: dict, ignore_fk: typing.Callable[[str], bool], + table_names: typing.Optional[frozenset] = None, ) -> Column: """ Produce column from aspects of its dict description. @@ -231,7 +282,7 @@ def dict_to_column( if "foreign_keys" in rep: args = [ ForeignKey( - fk, + unqualify_fk_target(fk, table_names), name=make_foreign_key_name(table_name, col_name), ondelete="CASCADE", ) @@ -246,6 +297,7 @@ def dict_to_column( type_=type_, primary_key=rep.get("primary", False), nullable=rep.get("nullable", None), + autoincrement=False, ) @@ -282,13 +334,14 @@ def dict_to_table( meta: MetaData, table_dict: TableT, ignore_fk: typing.Callable[[str], bool], + table_names: typing.Optional[frozenset] = None, ) -> Table: """Create a Table from its description.""" return Table( name, meta, *[ - dict_to_column(name, colname, col, ignore_fk) + dict_to_column(name, colname, col, ignore_fk, table_names) for (colname, col) in table_dict.get("columns", {}).items() ], *[dict_to_unique(constraint) for constraint in table_dict.get("unique", [])], @@ -328,7 +381,14 @@ def should_ignore_fk(tables_dict: dict[str, TableT], fk: str) -> bool: :param fk: The name of the foreign key. """ (table, _column) = split_column_full_name(fk) - td: dict[str, TableT] = get_property(tables_dict, table, {}) + # FK targets may be schema-qualified (e.g. "mimic100.concept"). + # Try the fully-qualified name first so users can be explicit in config + # (e.g. "mimic100.concept: ignore: true"); fall back to the bare table + # name for configs that don't include a schema prefix. + td = tables_dict.get(table) + if td is None: + bare = table.rsplit(".", maxsplit=1)[-1] + td = tables_dict.get(bare, {}) return get_property(td, "ignore", False) @@ -355,7 +415,8 @@ def dict_to_metadata( ignore_fk = partial(should_ignore_fk, tables_config) else: ignore_fk = _always_false + table_names = frozenset(tables_dict.keys()) meta = MetaData() for k, td in tables_dict.items(): - dict_to_table(k, meta, td, ignore_fk) + dict_to_table(k, meta, td, ignore_fk, table_names) return meta diff --git a/datafaker/utils.py b/datafaker/utils.py index c8bcc97e..5817502d 100644 --- a/datafaker/utils.py +++ b/datafaker/utils.py @@ -8,6 +8,7 @@ import re import string import sys +import typing from collections.abc import Mapping, MutableSequence, Sequence, Sized from pathlib import Path from types import ModuleType @@ -16,6 +17,7 @@ import yaml from jsonschema.exceptions import ValidationError from jsonschema.validators import validate +from sqlalchemy.engine import make_url from datafaker.settings import SettingsError @@ -92,6 +94,44 @@ def import_file(file_path: str) -> ModuleType: return module +_ASYNC_DRIVER_MAP: dict[str, str] = { + "postgresql": "postgresql+asyncpg", + "mssql": "mssql+aioodbc", +} + + +def make_async_dsn(db_dsn: str) -> str: + """Return an async-driver DSN for the given sync DSN. + + Replaces the driver component based on the dialect so that both PostgreSQL + and MS-SQL connections can be made async without hardcoding dialect names at + each call site. Raises ``ValueError`` for dialects with no known async driver. + """ + url = make_url(db_dsn) + dialect = url.drivername.split("+")[0] + async_driver = _ASYNC_DRIVER_MAP.get(dialect) + if async_driver is None: + raise ValueError( + f"No async driver is registered for dialect '{dialect}'. " + f"Add an entry to _ASYNC_DRIVER_MAP in datafaker/utils.py." + ) + return str(url.set(drivername=async_driver)) + + +def schema_qualified_name(table_name: str, engine: Any) -> str: + """Return schema-qualified table name using the engine's schema_translate_map. + + When create_db_engine sets schema_translate_map={None: schema_name}, this + reads it back so raw SQL strings (which schema_translate_map doesn't rewrite) + can include the correct qualifier. + """ + schema_map = engine.get_execution_options().get("schema_translate_map", {}) + schema = schema_map.get(None) + if schema and "." not in table_name: + return f"{schema}.{table_name}" + return table_name + + def info_or_lower(record: logging.LogRecord) -> bool: """Allow records with level of INFO or lower.""" return record.levelno in (logging.DEBUG, logging.INFO) @@ -524,6 +564,27 @@ def generators_require_stats(config: Mapping) -> bool: return "SRC_STATS" in symbols +def unqualify_fk_target(fk: str, table_names: typing.Optional[frozenset] = None) -> str: + """ + Drop the schema qualifier from a 3-part FK target. + + Converts ``schema.table.column`` → ``table.column`` so that SQLAlchemy + can resolve the reference against a MetaData whose tables were registered + without a schema prefix. 2-part ``table.column`` targets are returned + unchanged. + + When ``table_names`` is supplied, a 3-part target whose first two parts + form a known table name (e.g. ``manufacturer.parquet``) is left unchanged + because the dot is part of the table name, not a schema prefix. + """ + parts = fk.split(".") + if len(parts) == 3: + if table_names is not None and f"{parts[0]}.{parts[1]}" in table_names: + return fk + return f"{parts[1]}.{parts[2]}" + return fk + + def split_column_full_name(col_fullname: str) -> tuple[str, str]: """ Split a column fullname into table and column. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..fb63da4f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +services: + mssql: + image: mcr.microsoft.com/mssql/server:2022-latest + environment: + ACCEPT_EULA: "Y" + MSSQL_SA_PASSWORD: "Datafaker!Test123" + ports: + - "21433:1433" + healthcheck: + test: + - "CMD" + - "/opt/mssql-tools18/bin/sqlcmd" + - "-S" + - "localhost" + - "-U" + - "sa" + - "-P" + - "Datafaker!Test123" + - "-Q" + - "SELECT 1" + - "-No" + interval: 10s + timeout: 5s + retries: 12 + start_period: 30s diff --git a/docs/source/installation.rst b/docs/source/installation.rst index debf2d4f..6ce82b04 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -22,7 +22,7 @@ Then close your command shell and open another. Now you can use ``pipx``. .. code-block:: console - $ pipx install git+https://github.com/tim-band/sqlsynthgen + $ pipx install git+https://github.com/safehr-data/datafaker Check that you can view the help message with: @@ -30,5 +30,51 @@ Check that you can view the help message with: $ datafaker --help +If you need to use MS SQL (such as SQL Server) you need to install and register an ODBC driver. + +Install and register the ODBC driver +------------------------------------ + +Mac OS +^^^^^^ + +If you do not already have the Microsoft ODBC driver installed: + +.. code-block:: console + + $ brew tap microsoft/mssql-release + $ brew install unixodbc msodbcsql18 mssql-tools18 + +Then verify the driver is registered: + +.. code-block:: console + + $ odbcinst -q -d + +If the output is empty, register it manually: + +.. code-block:: console + + $ cat >> /opt/homebrew/etc/odbcinst.ini <<'EOF' + [ODBC Driver 18 for SQL Server] + Description=Microsoft ODBC Driver 18 for SQL Server + Driver=/opt/homebrew/lib/libmsodbcsql.18.dylib + UsageCount=1 + EOF + +Ubuntu +^^^^^^ + +Install and check the MS SQL tools: + +.. code-block:: console + + $ sudo apt install mssql-tools18 + $ odbcinst -q -d + [ODBC Driver 18 for SQL Server] + +Use in a docker container +========================= + It can also be used directly within a Docker container by downloading image ``timband/datafaker``. See the :ref:`quickstart guide ` for more information. diff --git a/examples/omop-mssql/.env.example b/examples/omop-mssql/.env.example new file mode 100644 index 00000000..83453da2 --- /dev/null +++ b/examples/omop-mssql/.env.example @@ -0,0 +1,4 @@ +SRC_DSN=mssql+pyodbc://:@127.0.0.1:1433/?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes +SRC_SCHEMA= +DST_DSN=mssql+pyodbc://:@127.0.0.1:1433/?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes +DST_SCHEMA= diff --git a/examples/omop-mssql/README.md b/examples/omop-mssql/README.md new file mode 100644 index 00000000..7c0bbfed --- /dev/null +++ b/examples/omop-mssql/README.md @@ -0,0 +1,148 @@ +# How to run datafaker process on OMOP schema with MS SQL Server + +## About + +This example is for testing datafaker against a Microsoft SQL Server (MS-SQL) database using the OMOP schema. It can be used to verify that datafaker correctly generates and manages synthetic data in an MS-SQL environment. + +## Challenges for MS-SQL support + +Datafaker was built with PostgreSQL as its primary target. The following issues need to be addressed to support MS-SQL (Microsoft SQL Server). + +### 1. Driver dependency ([#93](https://github.com/SAFEHR-data/datafaker/issues/93)) + +`psycopg2` (PostgreSQL driver) is a hard dependency imported directly in [datafaker/utils.py](../../datafaker/utils.py). MS-SQL requires a different driver such as `pyodbc` or `pymssql`, which are not currently listed in `pyproject.toml`. The `asyncpg` async driver is also PostgreSQL-specific; MS-SQL async support would require `aioodbc` or similar. + +### 2. Hardcoded async connection string rewriting ([#94](https://github.com/SAFEHR-data/datafaker/issues/94)) + +In [datafaker/utils.py:208](../../datafaker/utils.py), the async DSN is built by string-replacing `postgresql://` with `postgresql+asyncpg://`. This logic would silently fail (or produce a malformed DSN) for an `mssql://` connection string. + +### 3. PostgreSQL `search_path` for schema selection ([#95](https://github.com/SAFEHR-data/datafaker/issues/95)) + +When a schema name is provided, the code issues `SET search_path TO ` via a connection-level event listener ([datafaker/utils.py:222, 305](../../datafaker/utils.py)). This is PostgreSQL-specific syntax. MS-SQL uses two-part `[schema].[table]` naming and does not support `SET search_path`. SQLAlchemy's `schema` argument on `MetaData` and `Table` objects is the correct cross-dialect approach. + +### 4. PostgreSQL-specific column types in the type parser ([#96](https://github.com/SAFEHR-data/datafaker/issues/96), commit [76fec75](https://github.com/SAFEHR-data/datafaker/commit/76fec75)) + +[datafaker/serialize_metadata.py](../../datafaker/serialize_metadata.py) registers parsers for several PostgreSQL-only types that have no direct MS-SQL equivalent: + +| PostgreSQL type | MS-SQL equivalent / issue | +|---|---| +| `postgresql.TSVECTOR` | No native equivalent (full-text indexing works differently) | +| `postgresql.CIDR` | No native network address type | +| `postgresql.BYTEA` | Use `VARBINARY(MAX)` | +| `postgresql.ARRAY` | Not supported; would need denormalisation or JSON | +| `postgresql.ENUM` | Implemented via `CHECK` constraint or lookup table | +| `postgresql.DOMAIN` | Not supported | +| `postgresql.BIT` | MS-SQL `BIT` is boolean (0/1 only); multi-bit columns use `BINARY` | +| `postgresql.REAL` / `TIMESTAMP` / `TIME` with timezone | Need MS-SQL dialect equivalents (`DATETIMEOFFSET` for tz-aware timestamps) | + +### 5. `SERIAL` autoincrement columns ([#97](https://github.com/SAFEHR-data/datafaker/issues/97), commit [da4a69b](https://github.com/SAFEHR-data/datafaker/commit/da4a69b)) + +PostgreSQL uses `SERIAL` for autoincrement columns. The code already strips `SERIAL` for DuckDB in [datafaker/create.py:29](../../datafaker/create.py), but there is no equivalent handler for MS-SQL, which uses `IDENTITY(1,1)`. + +### 6. `postgresql.UUID` type mapping ([#98](https://github.com/SAFEHR-data/datafaker/issues/98), commit [76fec75](https://github.com/SAFEHR-data/datafaker/commit/76fec75)) + +[datafaker/make.py:384](../../datafaker/make.py) maps `postgresql.UUID` to a generator. MS-SQL uses `UNIQUEIDENTIFIER` for UUIDs, which SQLAlchemy exposes as `sqlalchemy.dialects.mssql.UNIQUEIDENTIFIER`. + +### 7. PostgreSQL-specific error handling (commits [b2f14ab](https://github.com/SAFEHR-data/datafaker/commit/b2f14ab), [39709d8](https://github.com/SAFEHR-data/datafaker/commit/39709d8)) + +[datafaker/utils.py:651](../../datafaker/utils.py) catches `psycopg2.errors.UndefinedObject` to handle missing constraints gracefully. This is a PostgreSQL/psycopg2-specific exception. For MS-SQL the equivalent `pyodbc` error would need to be caught instead, or the check should be made dialect-agnostic. + +### 8. `autocommit` handling in `set_db_settings` ([#99](https://github.com/SAFEHR-data/datafaker/issues/99)) + +[datafaker/utils.py:297-309](../../datafaker/utils.py) toggles `connection.autocommit` directly on the DBAPI connection before executing `SET` commands. The availability and behaviour of `autocommit` differs between `psycopg2`, `pyodbc`, and `pymssql`, so this would need testing or an abstraction per driver. + +**Deferred.** `set_db_settings` is only ever called for DuckDB connections (`parquet_dir` source feature); MS-SQL connections never reach it. Fixing the `autocommit` toggle in isolation would also leave the `SET {k} TO {v}` SQL syntax broken for MS-SQL (which requires `SET {k} {v}`). Both issues should be addressed together if `set_db_settings` is ever extended to MS-SQL. + +## Setup + +### 1. Install the MS-SQL Python extras + +`pyodbc` and `aioodbc` are optional dependencies. Install them with: + +```bash +poetry install --extras mssql +``` + +### 2. Install and register the ODBC driver + +#### mac OS + +If you do not already have the Microsoft ODBC driver installed: + +```bash +brew tap microsoft/mssql-release +brew install unixodbc msodbcsql18 mssql-tools18 +``` + +Then verify the driver is registered: + +```bash +odbcinst -q -d +``` + +If the output is empty, register it manually: + +```bash +cat >> /opt/homebrew/etc/odbcinst.ini <<'EOF' +[ODBC Driver 18 for SQL Server] +Description=Microsoft ODBC Driver 18 for SQL Server +Driver=/opt/homebrew/lib/libmsodbcsql.18.dylib +UsageCount=1 +EOF +``` + +#### Ubuntu + +Install and check the MS SQL tools: + +```console +$ sudo apt install mssql-tools18 +$ odbcinst -q -d +[ODBC Driver 18 for SQL Server] +``` + +### 3. Configure the connection + +Copy the example environment file and fill in your connection details: + +```bash +cp examples/omop-mssql/.env.example examples/omop-mssql/.env +``` + +Edit `.env` with your server hostname, credentials, database name and schema names. The DSN format is: + +`mssql+pyodbc://:@:1433/?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes` + +> **Note for Docker on macOS:** use `127.0.0.1` rather than `localhost`. macOS resolves `localhost` to `::1` (IPv6) but Docker Desktop's port forwarding only reliably maps the IPv4 address. + +Run datafaker commands from the `examples/omop-mssql/` directory so that the `.env` file is picked up automatically. + +## Steps + +Run all commands from the `examples/omop-mssql/` directory so that the `.env` file is picked up automatically. + +```bash +cd examples/omop-mssql +``` + +1. Make a YAML file representing the tables in the schema + +`poetry run datafaker make-tables --orm-file ./orm.yaml` + +1. Create schema from the ORM YAML file + +`poetry run datafaker create-tables --orm-file ./orm.yaml --config-file ./config.yaml` + +1. Run `copy_vocabulary.sql` to copy vocabulary table rows. (I did it in DBeaver) + +1. Create generator table + +`poetry run datafaker create-generators --orm-file ./orm.yaml --config-file ./config.yaml --df-file ./df.py` + +1. Create data + +`poetry run datafaker create-data --orm-file ./orm.yaml --config-file ./config.yaml --df-file ./df.py` + +1. Remove data + +`poetry run datafaker remove-data --orm-file ./orm.yaml --config-file ./config.yaml` diff --git a/examples/omop-mssql/config.yaml b/examples/omop-mssql/config.yaml new file mode 100644 index 00000000..d58d83d5 --- /dev/null +++ b/examples/omop-mssql/config.yaml @@ -0,0 +1,46 @@ +src-stats: +- comments: + - The values and their counts that appear in column gender_concept_id of a random + sample of 500 rows of table person + name: auto__person__gender_concept_id + query: "SELECT _counted.value, _counted.count \nFROM (SELECT _inner.value AS value,\ + \ count(_inner.value) AS count \nFROM (SELECT TOP 500 \"gender_concept_id\" AS\ + \ value \nFROM mimic100.person \nWHERE \"gender_concept_id\" IS NOT NULL ORDER\ + \ BY newid()) AS _inner GROUP BY _inner.value) AS _counted ORDER BY _counted.count\ + \ DESC" +- comments: + - All the values that appear in column year_of_birth of table person + name: auto__person__year_of_birth + query: "SELECT _counted.value \nFROM (SELECT \"year_of_birth\" AS value, count(\"\ + year_of_birth\") AS count \nFROM mimic100.person \nWHERE \"year_of_birth\" IS\ + \ NOT NULL GROUP BY \"year_of_birth\") AS _counted ORDER BY _counted.count DESC" +- comments: + - All the values that appear in column ethnicity_concept_id of table person more + than 7 times + name: auto__person__ethnicity_concept_id + query: "SELECT _counted.value \nFROM (SELECT \"ethnicity_concept_id\" AS value,\ + \ count(\"ethnicity_concept_id\") AS count \nFROM mimic100.person \nWHERE \"ethnicity_concept_id\"\ + \ IS NOT NULL GROUP BY \"ethnicity_concept_id\") AS _counted \nWHERE _counted.count\ + \ > 7" +tables: + concept: + ignore: false + vocabulary_table: true + person: + num_rows_per_pass: 10 + row_generators: + - columns_assigned: + - gender_concept_id + kwargs: + a: SRC_STATS["auto__person__gender_concept_id"]["results"] + name: dist_gen.weighted_choice + - columns_assigned: + - year_of_birth + kwargs: + a: SRC_STATS["auto__person__year_of_birth"]["results"] + name: dist_gen.choice + - columns_assigned: + - ethnicity_concept_id + kwargs: + a: SRC_STATS["auto__person__ethnicity_concept_id"]["results"] + name: dist_gen.choice diff --git a/examples/omop-mssql/df.py b/examples/omop-mssql/df.py new file mode 100644 index 00000000..445f7f7f --- /dev/null +++ b/examples/omop-mssql/df.py @@ -0,0 +1,88 @@ +"""This file was auto-generated by datafaker but can be edited manually.""" +from mimesis import Generic, Numeric, Person +from mimesis.locales import Locale +import sqlalchemy +import sys +from datafaker.base import FileUploader, TableGenerator, ColumnPresence +from datafaker.providers import DistributionProvider + +generic = Generic(locale=Locale.EN_GB) +numeric = Numeric() +person = Person() +dist_gen = DistributionProvider() +column_presence = ColumnPresence() + +sys.path.append("") + +from datafaker.providers import ( + BytesProvider, + ColumnValueProvider, + DistributionProvider, + NullProvider, + SQLGroupByProvider, + TimedeltaProvider, + TimespanProvider, + WeightedBooleanProvider, +) + +generic.add_provider(BytesProvider) +generic.add_provider(ColumnValueProvider) +generic.add_provider(DistributionProvider) +generic.add_provider(NullProvider) +generic.add_provider(SQLGroupByProvider) +generic.add_provider(TimedeltaProvider) +generic.add_provider(TimespanProvider) +generic.add_provider(WeightedBooleanProvider) + + +import yaml + +with open("src-stats.yaml", "r", encoding="utf-8") as f: + SRC_STATS = yaml.unsafe_load(f) + + +class PersonGenerator(TableGenerator): + num_rows_per_pass = 10 + + def __init__(self): + self.initialized = False + + def __call__(self, dst_db_conn, metadata): + if not self.initialized: + self.initialized = True + result = {} + columns_to_generate = set( + { + "ethnicity_concept_id", + "race_concept_id", + "gender_concept_id", + "year_of_birth", + } + ) + while columns_to_generate: + if "gender_concept_id" in columns_to_generate: + result["gender_concept_id"] = dist_gen.weighted_choice( + a=SRC_STATS["auto__person__gender_concept_id"]["results"] + ) + if "year_of_birth" in columns_to_generate: + result["year_of_birth"] = dist_gen.choice( + a=SRC_STATS["auto__person__year_of_birth"]["results"] + ) + if "ethnicity_concept_id" in columns_to_generate: + result["ethnicity_concept_id"] = dist_gen.choice( + a=SRC_STATS["auto__person__ethnicity_concept_id"]["results"] + ) + if "race_concept_id" in columns_to_generate: + result["race_concept_id"] = generic.column_value_provider.column_value( + dst_db_conn, metadata.tables["concept"], "concept_id" + ) + columns_to_generate = set() + return result + + +table_generator_dict = { + "person": PersonGenerator(), +} + + +story_generator_list = [] diff --git a/examples/omop-mssql/orm.yaml b/examples/omop-mssql/orm.yaml new file mode 100644 index 00000000..2aedbf3f --- /dev/null +++ b/examples/omop-mssql/orm.yaml @@ -0,0 +1,121 @@ +dsn: mssql+pyodbc://sa:***@127.0.0.1:1433/master?TrustServerCertificate=yes&driver=ODBC+Driver+18+for+SQL+Server +schema: mimic100 +tables: + concept: + columns: + concept_class_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + concept_code: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + concept_id: + nullable: false + primary: true + type: BIGINT + concept_name: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + domain_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + standard_concept: + nullable: true + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + vocabulary_id: + nullable: false + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + person: + columns: + # birth_datetime: + # nullable: true + # primary: false + # type: DATETIME2 + # day_of_birth: + # nullable: true + # primary: false + # type: BIGINT + ethnicity_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + # ethnicity_source_concept_id: + # foreign_keys: + # - mimic100.concept.concept_id + # nullable: true + # primary: false + # type: BIGINT + # ethnicity_source_value: + # nullable: true + # primary: false + # type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + gender_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + # gender_source_concept_id: + # foreign_keys: + # - mimic100.concept.concept_id + # nullable: true + # primary: false + # type: BIGINT + # gender_source_value: + # nullable: true + # primary: false + # type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + # month_of_birth: + # nullable: true + # primary: false + # type: BIGINT + person_id: + nullable: false + primary: true + type: BIGINT + # person_source_value: + # nullable: true + # primary: false + # type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + race_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + # race_source_concept_id: + # foreign_keys: + # - mimic100.concept.concept_id + # nullable: true + # primary: false + # type: BIGINT + # race_source_value: + # nullable: true + # primary: false + # type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + year_of_birth: + nullable: false + primary: false + type: BIGINT + unique: [] diff --git a/examples/omop-mssql/orm_full.yaml b/examples/omop-mssql/orm_full.yaml new file mode 100644 index 00000000..d4ccf16b --- /dev/null +++ b/examples/omop-mssql/orm_full.yaml @@ -0,0 +1,1868 @@ +dsn: mssql+pyodbc://sa:***@127.0.0.1:1433/master?TrustServerCertificate=yes&driver=ODBC+Driver+18+for+SQL+Server +schema: mimic100 +tables: + care_site: + columns: + care_site_id: + nullable: false + primary: true + type: BIGINT + care_site_name: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + care_site_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + location_id: + nullable: true + primary: false + type: BIGINT + place_of_service_concept_id: + nullable: true + primary: false + type: BIGINT + place_of_service_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + cdm_source: + columns: + cdm_etl_reference: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + cdm_holder: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + cdm_release_date: + nullable: false + primary: false + type: DATE + cdm_source_abbreviation: + nullable: false + primary: false + type: VARCHAR(25) COLLATE SQL_Latin1_General_CP1_CI_AS + cdm_source_name: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + cdm_version: + nullable: true + primary: false + type: VARCHAR(10) COLLATE SQL_Latin1_General_CP1_CI_AS + source_description: + nullable: true + primary: false + type: VARCHAR(max) COLLATE SQL_Latin1_General_CP1_CI_AS + source_documentation_reference: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + source_release_date: + nullable: false + primary: false + type: DATE + vocabulary_version: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + cohort: + columns: + cohort_definition_id: + nullable: false + primary: false + type: BIGINT + cohort_end_date: + nullable: false + primary: false + type: DATE + cohort_start_date: + nullable: false + primary: false + type: DATE + subject_id: + nullable: false + primary: false + type: BIGINT + unique: [] + cohort_definition: + columns: + cohort_definition_description: + nullable: true + primary: false + type: VARCHAR(max) COLLATE SQL_Latin1_General_CP1_CI_AS + cohort_definition_id: + nullable: false + primary: false + type: BIGINT + cohort_definition_name: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + cohort_definition_syntax: + nullable: true + primary: false + type: VARCHAR(max) COLLATE SQL_Latin1_General_CP1_CI_AS + cohort_initiation_date: + nullable: true + primary: false + type: DATE + definition_type_concept_id: + nullable: false + primary: false + type: BIGINT + subject_concept_id: + nullable: false + primary: false + type: BIGINT + unique: [] + concept: + columns: + concept_class_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + concept_code: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + concept_id: + nullable: false + primary: true + type: BIGINT + concept_name: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + domain_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + standard_concept: + nullable: true + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + vocabulary_id: + nullable: false + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + concept_ancestor: + columns: + ancestor_concept_id: + nullable: false + primary: false + type: BIGINT + descendant_concept_id: + nullable: false + primary: false + type: BIGINT + max_levels_of_separation: + nullable: false + primary: false + type: BIGINT + min_levels_of_separation: + nullable: false + primary: false + type: BIGINT + unique: [] + concept_class: + columns: + concept_class_concept_id: + nullable: false + primary: false + type: BIGINT + concept_class_id: + nullable: false + primary: true + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + concept_class_name: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + concept_relationship: + columns: + concept_id_1: + nullable: false + primary: false + type: BIGINT + concept_id_2: + nullable: false + primary: false + type: BIGINT + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + relationship_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + unique: [] + concept_synonym: + columns: + concept_id: + nullable: false + primary: false + type: BIGINT + concept_synonym_name: + nullable: false + primary: false + type: VARCHAR(1000) COLLATE SQL_Latin1_General_CP1_CI_AS + language_concept_id: + nullable: false + primary: false + type: BIGINT + unique: [] + condition_era: + columns: + condition_concept_id: + nullable: false + primary: false + type: BIGINT + condition_era_end_date: + nullable: false + primary: false + type: DATE + condition_era_id: + nullable: false + primary: true + type: BIGINT + condition_era_start_date: + nullable: false + primary: false + type: DATE + condition_occurrence_count: + nullable: true + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + unique: [] + condition_occurrence: + columns: + condition_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + condition_end_date: + nullable: true + primary: false + type: DATE + condition_end_datetime: + nullable: true + primary: false + type: DATETIME2 + condition_occurrence_id: + nullable: false + primary: true + type: BIGINT + condition_source_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + condition_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + condition_start_date: + nullable: false + primary: false + type: DATE + condition_start_datetime: + nullable: true + primary: false + type: DATETIME2 + condition_status_concept_id: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + condition_status_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + condition_type_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - mimic100.person.person_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - mimic100.provider.provider_id + nullable: true + primary: false + type: BIGINT + stop_reason: + nullable: true + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + visit_detail_id: + foreign_keys: + - mimic100.visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - mimic100.visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + cost: + columns: + amount_allowed: + nullable: true + primary: false + type: NUMERIC(18, 0) + cost_domain_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + cost_event_id: + nullable: false + primary: false + type: BIGINT + cost_id: + nullable: false + primary: true + type: BIGINT + cost_type_concept_id: + nullable: false + primary: false + type: BIGINT + currency_concept_id: + nullable: true + primary: false + type: BIGINT + drg_concept_id: + nullable: true + primary: false + type: BIGINT + drg_source_value: + nullable: true + primary: false + type: VARCHAR(3) COLLATE SQL_Latin1_General_CP1_CI_AS + paid_by_patient: + nullable: true + primary: false + type: NUMERIC(18, 0) + paid_by_payer: + nullable: true + primary: false + type: NUMERIC(18, 0) + paid_by_primary: + nullable: true + primary: false + type: NUMERIC(18, 0) + paid_dispensing_fee: + nullable: true + primary: false + type: NUMERIC(18, 0) + paid_ingredient_cost: + nullable: true + primary: false + type: NUMERIC(18, 0) + paid_patient_coinsurance: + nullable: true + primary: false + type: NUMERIC(18, 0) + paid_patient_copay: + nullable: true + primary: false + type: NUMERIC(18, 0) + paid_patient_deductible: + nullable: true + primary: false + type: NUMERIC(18, 0) + payer_plan_period_id: + nullable: true + primary: false + type: BIGINT + revenue_code_concept_id: + nullable: true + primary: false + type: BIGINT + revenue_code_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + total_charge: + nullable: true + primary: false + type: NUMERIC(18, 0) + total_cost: + nullable: true + primary: false + type: NUMERIC(18, 0) + total_paid: + nullable: true + primary: false + type: NUMERIC(18, 0) + unique: [] + death: + columns: + cause_concept_id: + nullable: true + primary: false + type: BIGINT + cause_source_concept_id: + nullable: true + primary: false + type: BIGINT + cause_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + death_date: + nullable: false + primary: false + type: DATE + death_datetime: + nullable: true + primary: false + type: DATETIME2 + death_type_concept_id: + nullable: true + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + unique: [] + device_exposure: + columns: + device_concept_id: + nullable: false + primary: false + type: BIGINT + device_exposure_end_date: + nullable: true + primary: false + type: DATE + device_exposure_end_datetime: + nullable: true + primary: false + type: DATETIME2 + device_exposure_id: + nullable: false + primary: true + type: BIGINT + device_exposure_start_date: + nullable: false + primary: false + type: DATE + device_exposure_start_datetime: + nullable: true + primary: false + type: DATETIME2 + device_source_concept_id: + nullable: true + primary: false + type: BIGINT + device_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + device_type_concept_id: + nullable: false + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + provider_id: + nullable: true + primary: false + type: BIGINT + quantity: + nullable: true + primary: false + type: BIGINT + unique_device_id: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + visit_detail_id: + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + nullable: true + primary: false + type: BIGINT + unique: [] + domain: + columns: + domain_concept_id: + nullable: false + primary: false + type: BIGINT + domain_id: + nullable: false + primary: true + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + domain_name: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + dose_era: + columns: + dose_era_end_date: + nullable: false + primary: false + type: DATE + dose_era_id: + nullable: false + primary: true + type: BIGINT + dose_era_start_date: + nullable: false + primary: false + type: DATE + dose_value: + nullable: false + primary: false + type: NUMERIC(18, 0) + drug_concept_id: + nullable: false + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + unit_concept_id: + nullable: false + primary: false + type: BIGINT + unique: [] + drug_era: + columns: + drug_concept_id: + nullable: false + primary: false + type: BIGINT + drug_era_end_date: + nullable: false + primary: false + type: DATE + drug_era_id: + nullable: false + primary: true + type: BIGINT + drug_era_start_date: + nullable: false + primary: false + type: DATE + drug_exposure_count: + nullable: true + primary: false + type: BIGINT + gap_days: + nullable: true + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + unique: [] + drug_exposure: + columns: + days_supply: + nullable: true + primary: false + type: BIGINT + dose_unit_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + drug_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + drug_exposure_end_date: + nullable: false + primary: false + type: DATE + drug_exposure_end_datetime: + nullable: true + primary: false + type: DATETIME2 + drug_exposure_id: + nullable: false + primary: true + type: BIGINT + drug_exposure_start_date: + nullable: false + primary: false + type: DATE + drug_exposure_start_datetime: + nullable: true + primary: false + type: DATETIME2 + drug_source_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + drug_source_value: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + drug_type_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + lot_number: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + person_id: + foreign_keys: + - mimic100.person.person_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - mimic100.provider.provider_id + nullable: true + primary: false + type: BIGINT + quantity: + nullable: true + primary: false + type: NUMERIC(18, 0) + refills: + nullable: true + primary: false + type: BIGINT + route_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + route_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + sig: + nullable: true + primary: false + type: VARCHAR(max) COLLATE SQL_Latin1_General_CP1_CI_AS + stop_reason: + nullable: true + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + verbatim_end_date: + nullable: true + primary: false + type: DATE + visit_detail_id: + foreign_keys: + - mimic100.visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - mimic100.visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + drug_strength: + columns: + amount_unit_concept_id: + nullable: true + primary: false + type: BIGINT + amount_value: + nullable: true + primary: false + type: NUMERIC(18, 0) + box_size: + nullable: true + primary: false + type: BIGINT + denominator_unit_concept_id: + nullable: true + primary: false + type: BIGINT + denominator_value: + nullable: true + primary: false + type: NUMERIC(18, 0) + drug_concept_id: + nullable: false + primary: false + type: BIGINT + ingredient_concept_id: + nullable: false + primary: false + type: BIGINT + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + numerator_unit_concept_id: + nullable: true + primary: false + type: BIGINT + numerator_value: + nullable: true + primary: false + type: NUMERIC(18, 0) + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + unique: [] + episode: + columns: + episode_concept_id: + nullable: false + primary: false + type: BIGINT + episode_end_date: + nullable: true + primary: false + type: DATE + episode_end_datetime: + nullable: true + primary: false + type: DATETIME2 + episode_id: + nullable: false + primary: true + type: BIGINT + episode_number: + nullable: true + primary: false + type: BIGINT + episode_object_concept_id: + nullable: false + primary: false + type: BIGINT + episode_parent_id: + nullable: true + primary: false + type: BIGINT + episode_source_concept_id: + nullable: true + primary: false + type: BIGINT + episode_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + episode_start_date: + nullable: false + primary: false + type: DATE + episode_start_datetime: + nullable: true + primary: false + type: DATETIME2 + episode_type_concept_id: + nullable: false + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + unique: [] + episode_event: + columns: + episode_event_field_concept_id: + nullable: false + primary: false + type: BIGINT + episode_id: + nullable: false + primary: false + type: BIGINT + event_id: + nullable: false + primary: false + type: BIGINT + unique: [] + fact_relationship: + columns: + domain_concept_id_1: + nullable: false + primary: false + type: BIGINT + domain_concept_id_2: + nullable: false + primary: false + type: BIGINT + fact_id_1: + nullable: false + primary: false + type: BIGINT + fact_id_2: + nullable: false + primary: false + type: BIGINT + relationship_concept_id: + nullable: false + primary: false + type: BIGINT + unique: [] + location: + columns: + address_1: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + address_2: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + city: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + county: + nullable: true + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + location_id: + nullable: false + primary: true + type: BIGINT + location_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + state: + nullable: true + primary: false + type: VARCHAR(2) COLLATE SQL_Latin1_General_CP1_CI_AS + zip: + nullable: true + primary: false + type: VARCHAR(9) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + measurement: + columns: + measurement_concept_id: + nullable: false + primary: false + type: BIGINT + measurement_date: + nullable: false + primary: false + type: DATE + measurement_datetime: + nullable: true + primary: false + type: DATETIME2 + measurement_id: + nullable: false + primary: true + type: BIGINT + measurement_source_concept_id: + nullable: true + primary: false + type: BIGINT + measurement_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + measurement_time: + nullable: true + primary: false + type: VARCHAR(10) COLLATE SQL_Latin1_General_CP1_CI_AS + measurement_type_concept_id: + nullable: false + primary: false + type: BIGINT + operator_concept_id: + nullable: true + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + provider_id: + nullable: true + primary: false + type: BIGINT + range_high: + nullable: true + primary: false + type: NUMERIC(18, 0) + range_low: + nullable: true + primary: false + type: NUMERIC(18, 0) + unit_concept_id: + nullable: true + primary: false + type: BIGINT + unit_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + value_as_concept_id: + nullable: true + primary: false + type: BIGINT + value_as_number: + nullable: true + primary: false + type: NUMERIC(18, 0) + value_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + visit_detail_id: + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + nullable: true + primary: false + type: BIGINT + unique: [] + metadata: + columns: + metadata_concept_id: + nullable: false + primary: false + type: BIGINT + metadata_date: + nullable: true + primary: false + type: DATE + metadata_datetime: + nullable: true + primary: false + type: DATETIME2 + metadata_id: + nullable: false + primary: true + type: BIGINT + metadata_type_concept_id: + nullable: false + primary: false + type: BIGINT + name: + nullable: false + primary: false + type: VARCHAR(250) COLLATE SQL_Latin1_General_CP1_CI_AS + value_as_concept_id: + nullable: true + primary: false + type: BIGINT + value_as_number: + nullable: true + primary: false + type: NUMERIC(18, 0) + value_as_string: + nullable: true + primary: false + type: VARCHAR(250) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + note: + columns: + encoding_concept_id: + nullable: false + primary: false + type: BIGINT + language_concept_id: + nullable: false + primary: false + type: BIGINT + note_class_concept_id: + nullable: false + primary: false + type: BIGINT + note_date: + nullable: false + primary: false + type: DATE + note_datetime: + nullable: true + primary: false + type: DATETIME2 + note_event_field_concept_id: + nullable: true + primary: false + type: BIGINT + note_event_id: + nullable: true + primary: false + type: BIGINT + note_id: + nullable: false + primary: true + type: BIGINT + note_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + note_text: + nullable: false + primary: false + type: VARCHAR(max) COLLATE SQL_Latin1_General_CP1_CI_AS + note_title: + nullable: true + primary: false + type: VARCHAR(250) COLLATE SQL_Latin1_General_CP1_CI_AS + note_type_concept_id: + nullable: false + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + provider_id: + nullable: true + primary: false + type: BIGINT + visit_detail_id: + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + nullable: true + primary: false + type: BIGINT + unique: [] + note_nlp: + columns: + lexical_variant: + nullable: false + primary: false + type: VARCHAR(250) COLLATE SQL_Latin1_General_CP1_CI_AS + nlp_date: + nullable: false + primary: false + type: DATE + nlp_datetime: + nullable: true + primary: false + type: DATETIME2 + nlp_system: + nullable: true + primary: false + type: VARCHAR(250) COLLATE SQL_Latin1_General_CP1_CI_AS + note_id: + nullable: false + primary: false + type: BIGINT + note_nlp_concept_id: + nullable: true + primary: false + type: BIGINT + note_nlp_id: + nullable: false + primary: true + type: BIGINT + note_nlp_source_concept_id: + nullable: true + primary: false + type: BIGINT + offset: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + section_concept_id: + nullable: true + primary: false + type: BIGINT + snippet: + nullable: true + primary: false + type: VARCHAR(250) COLLATE SQL_Latin1_General_CP1_CI_AS + term_exists: + nullable: true + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + term_modifiers: + nullable: true + primary: false + type: VARCHAR(2000) COLLATE SQL_Latin1_General_CP1_CI_AS + term_temporal: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + observation: + columns: + observation_concept_id: + nullable: false + primary: false + type: BIGINT + observation_date: + nullable: false + primary: false + type: DATE + observation_datetime: + nullable: true + primary: false + type: DATETIME2 + observation_id: + nullable: false + primary: true + type: BIGINT + observation_source_concept_id: + nullable: true + primary: false + type: BIGINT + observation_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + observation_type_concept_id: + nullable: false + primary: false + type: BIGINT + person_id: + nullable: false + primary: false + type: BIGINT + provider_id: + nullable: true + primary: false + type: BIGINT + qualifier_concept_id: + nullable: true + primary: false + type: BIGINT + qualifier_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + unit_concept_id: + nullable: true + primary: false + type: BIGINT + unit_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + value_as_concept_id: + nullable: true + primary: false + type: BIGINT + value_as_number: + nullable: true + primary: false + type: NUMERIC(18, 0) + value_as_string: + nullable: true + primary: false + type: VARCHAR(120) COLLATE SQL_Latin1_General_CP1_CI_AS + visit_detail_id: + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + nullable: true + primary: false + type: BIGINT + unique: [] + observation_period: + columns: + observation_period_end_date: + nullable: false + primary: false + type: DATE + observation_period_id: + nullable: false + primary: true + type: BIGINT + observation_period_start_date: + nullable: false + primary: false + type: DATE + period_type_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - mimic100.person.person_id + nullable: false + primary: false + type: BIGINT + unique: [] + payer_plan_period: + columns: + family_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + payer_concept_id: + nullable: true + primary: false + type: BIGINT + payer_plan_period_end_date: + nullable: false + primary: false + type: DATE + payer_plan_period_id: + nullable: false + primary: true + type: BIGINT + payer_plan_period_start_date: + nullable: false + primary: false + type: DATE + payer_source_concept_id: + nullable: true + primary: false + type: BIGINT + payer_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + person_id: + nullable: false + primary: false + type: BIGINT + plan_concept_id: + nullable: true + primary: false + type: BIGINT + plan_source_concept_id: + nullable: true + primary: false + type: BIGINT + plan_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + sponsor_concept_id: + nullable: true + primary: false + type: BIGINT + sponsor_source_concept_id: + nullable: true + primary: false + type: BIGINT + sponsor_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + stop_reason_concept_id: + nullable: true + primary: false + type: BIGINT + stop_reason_source_concept_id: + nullable: true + primary: false + type: BIGINT + stop_reason_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + person: + columns: + birth_datetime: + nullable: true + primary: false + type: DATETIME2 + care_site_id: + foreign_keys: + - mimic100.care_site.care_site_id + nullable: true + primary: false + type: BIGINT + day_of_birth: + nullable: true + primary: false + type: BIGINT + ethnicity_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + ethnicity_source_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + ethnicity_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + gender_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + gender_source_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + gender_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + location_id: + foreign_keys: + - mimic100.location.location_id + nullable: true + primary: false + type: BIGINT + month_of_birth: + nullable: true + primary: false + type: BIGINT + person_id: + nullable: false + primary: true + type: BIGINT + person_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + provider_id: + foreign_keys: + - mimic100.provider.provider_id + nullable: true + primary: false + type: BIGINT + race_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + race_source_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + race_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + year_of_birth: + nullable: false + primary: false + type: BIGINT + unique: [] + procedure_occurrence: + columns: + modifier_concept_id: + nullable: true + primary: false + type: BIGINT + modifier_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + person_id: + foreign_keys: + - mimic100.person.person_id + nullable: false + primary: false + type: BIGINT + procedure_concept_id: + nullable: false + primary: false + type: BIGINT + procedure_date: + nullable: false + primary: false + type: DATE + procedure_datetime: + nullable: true + primary: false + type: DATETIME2 + procedure_occurrence_id: + nullable: false + primary: true + type: BIGINT + procedure_source_concept_id: + nullable: true + primary: false + type: BIGINT + procedure_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + procedure_type_concept_id: + nullable: false + primary: false + type: BIGINT + provider_id: + nullable: true + primary: false + type: BIGINT + quantity: + nullable: true + primary: false + type: BIGINT + visit_detail_id: + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + nullable: true + primary: false + type: BIGINT + unique: [] + provider: + columns: + care_site_id: + nullable: true + primary: false + type: BIGINT + dea: + nullable: true + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + gender_concept_id: + nullable: true + primary: false + type: BIGINT + gender_source_concept_id: + nullable: true + primary: false + type: BIGINT + gender_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + npi: + nullable: true + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + provider_id: + nullable: false + primary: true + type: BIGINT + provider_name: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + provider_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + specialty_concept_id: + nullable: true + primary: false + type: BIGINT + specialty_source_concept_id: + nullable: true + primary: false + type: BIGINT + specialty_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + year_of_birth: + nullable: true + primary: false + type: BIGINT + unique: [] + relationship: + columns: + defines_ancestry: + nullable: false + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + is_hierarchical: + nullable: false + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + relationship_concept_id: + nullable: false + primary: false + type: BIGINT + relationship_id: + nullable: false + primary: true + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + relationship_name: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + reverse_relationship_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + source_to_concept_map: + columns: + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS + source_code: + nullable: false + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + source_code_description: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + source_concept_id: + nullable: false + primary: false + type: BIGINT + source_vocabulary_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + target_concept_id: + nullable: false + primary: false + type: BIGINT + target_vocabulary_id: + nullable: false + primary: false + type: VARCHAR(20) COLLATE SQL_Latin1_General_CP1_CI_AS + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + unique: [] + specimen: + columns: + anatomic_site_concept_id: + nullable: true + primary: false + type: BIGINT + anatomic_site_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + disease_status_concept_id: + nullable: true + primary: false + type: BIGINT + disease_status_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + person_id: + nullable: false + primary: false + type: BIGINT + quantity: + nullable: true + primary: false + type: NUMERIC(18, 0) + specimen_concept_id: + nullable: false + primary: false + type: BIGINT + specimen_date: + nullable: false + primary: false + type: DATE + specimen_datetime: + nullable: true + primary: false + type: DATETIME2 + specimen_id: + nullable: false + primary: true + type: BIGINT + specimen_source_id: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + specimen_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + specimen_type_concept_id: + nullable: false + primary: false + type: BIGINT + unit_concept_id: + nullable: true + primary: false + type: BIGINT + unit_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] + visit_detail: + columns: + admitting_source_concept_id: + nullable: true + primary: false + type: BIGINT + admitting_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + care_site_id: + foreign_keys: + - mimic100.care_site.care_site_id + nullable: true + primary: false + type: BIGINT + discharge_to_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + discharge_to_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + person_id: + foreign_keys: + - mimic100.person.person_id + nullable: false + primary: false + type: BIGINT + preceding_visit_detail_id: + foreign_keys: + - mimic100.visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + provider_id: + foreign_keys: + - mimic100.provider.provider_id + nullable: true + primary: false + type: BIGINT + visit_detail_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + visit_detail_end_date: + nullable: false + primary: false + type: DATE + visit_detail_end_datetime: + nullable: true + primary: false + type: DATETIME2 + visit_detail_id: + nullable: false + primary: true + type: BIGINT + visit_detail_parent_id: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + visit_detail_source_concept_id: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + visit_detail_source_value: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + visit_detail_start_date: + nullable: false + primary: false + type: DATE + visit_detail_start_datetime: + nullable: true + primary: false + type: DATETIME2 + visit_detail_type_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - mimic100.visit_occurrence.visit_occurrence_id + nullable: false + primary: false + type: BIGINT + unique: [] + visit_occurrence: + columns: + admitted_from_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + admitted_from_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + care_site_id: + foreign_keys: + - mimic100.care_site.care_site_id + nullable: true + primary: false + type: BIGINT + discharged_to_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + discharged_to_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + person_id: + foreign_keys: + - mimic100.person.person_id + nullable: false + primary: false + type: BIGINT + preceding_visit_occurrence_id: + foreign_keys: + - mimic100.visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + provider_id: + foreign_keys: + - mimic100.provider.provider_id + nullable: true + primary: false + type: BIGINT + visit_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + visit_end_date: + nullable: false + primary: false + type: DATE + visit_end_datetime: + nullable: true + primary: false + type: DATETIME2 + visit_occurrence_id: + nullable: false + primary: true + type: BIGINT + visit_source_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: true + primary: false + type: BIGINT + visit_source_value: + nullable: true + primary: false + type: VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS + visit_start_date: + nullable: false + primary: false + type: DATE + visit_start_datetime: + nullable: true + primary: false + type: DATETIME2 + visit_type_concept_id: + foreign_keys: + - mimic100.concept.concept_id + nullable: false + primary: false + type: BIGINT + unique: [] + vocabulary: + columns: + vocabulary_concept_id: + nullable: false + primary: false + type: BIGINT + vocabulary_id: + nullable: false + primary: true + type: VARCHAR(30) COLLATE SQL_Latin1_General_CP1_CI_AS + vocabulary_name: + nullable: false + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + vocabulary_reference: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + vocabulary_version: + nullable: true + primary: false + type: VARCHAR(255) COLLATE SQL_Latin1_General_CP1_CI_AS + unique: [] diff --git a/examples/omop-mssql/sql/copy_vocabulary.sql b/examples/omop-mssql/sql/copy_vocabulary.sql new file mode 100644 index 00000000..cc4b221f --- /dev/null +++ b/examples/omop-mssql/sql/copy_vocabulary.sql @@ -0,0 +1,24 @@ +INSERT INTO mimic100_synthetic.concept ( + concept_class_id, + concept_code, + concept_id, + concept_name, + domain_id, + invalid_reason, + standard_concept, + valid_end_date, + valid_start_date, + vocabulary_id +) +SELECT + concept_class_id, + concept_code, + concept_id, + concept_name, + domain_id, + invalid_reason, + standard_concept, + valid_end_date, + valid_start_date, + vocabulary_id +FROM mimic100.concept; diff --git a/examples/omop-mssql/src-stats.yaml b/examples/omop-mssql/src-stats.yaml new file mode 100644 index 00000000..17f5b399 --- /dev/null +++ b/examples/omop-mssql/src-stats.yaml @@ -0,0 +1,102 @@ +auto__person__ethnicity_concept_id: + comments: + - All the values that appear in column ethnicity_concept_id of table person more + than 7 times + queries: + date: '2026-05-22 15:26:05' + query: "SELECT _counted.value \nFROM (SELECT \"ethnicity_concept_id\" AS value,\ + \ count(\"ethnicity_concept_id\") AS count \nFROM mimic100.person \nWHERE \"\ + ethnicity_concept_id\" IS NOT NULL GROUP BY \"ethnicity_concept_id\") AS _counted\ + \ \nWHERE _counted.count > 7" + results: + - value: 0 +auto__person__gender_concept_id: + comments: + - The values and their counts that appear in column gender_concept_id of a random + sample of 500 rows of table person + queries: + date: '2026-05-22 15:26:05' + query: "SELECT _counted.value, _counted.count \nFROM (SELECT _inner.value AS value,\ + \ count(_inner.value) AS count \nFROM (SELECT TOP 500 \"gender_concept_id\"\ + \ AS value \nFROM mimic100.person \nWHERE \"gender_concept_id\" IS NOT NULL\ + \ ORDER BY newid()) AS _inner GROUP BY _inner.value) AS _counted ORDER BY _counted.count\ + \ DESC" + results: + - count: 57 + value: 8507 + - count: 43 + value: 8532 +auto__person__year_of_birth: + comments: + - All the values that appear in column year_of_birth of table person + queries: + date: '2026-05-22 15:26:05' + query: "SELECT _counted.value \nFROM (SELECT \"year_of_birth\" AS value, count(\"\ + year_of_birth\") AS count \nFROM mimic100.person \nWHERE \"year_of_birth\" IS\ + \ NOT NULL GROUP BY \"year_of_birth\") AS _counted ORDER BY _counted.count DESC" + results: + - value: 2062 + - value: 2058 + - value: 2059 + - value: 2070 + - value: 2073 + - value: 2084 + - value: 2119 + - value: 2123 + - value: 2125 + - value: 2102 + - value: 2104 + - value: 2106 + - value: 2136 + - value: 2130 + - value: 2133 + - value: 2055 + - value: 2085 + - value: 2086 + - value: 2089 + - value: 2094 + - value: 2075 + - value: 2079 + - value: 2083 + - value: 2066 + - value: 2043 + - value: 2050 + - value: 2052 + - value: 2054 + - value: 2049 + - value: 2030 + - value: 2031 + - value: 2033 + - value: 2038 + - value: 2041 + - value: 2067 + - value: 2069 + - value: 2064 + - value: 2060 + - value: 2061 + - value: 2077 + - value: 2074 + - value: 2071 + - value: 2095 + - value: 2096 + - value: 2097 + - value: 2099 + - value: 2090 + - value: 2092 + - value: 2093 + - value: 2134 + - value: 2138 + - value: 2145 + - value: 2149 + - value: 2108 + - value: 2111 + - value: 2114 + - value: 2115 + - value: 2116 + - value: 2117 + - value: 2118 + - value: 2105 + - value: 2103 + - value: 2128 + - value: 2120 + - value: 2122 diff --git a/examples/omop-postgresql/README.md b/examples/omop-postgresql/README.md new file mode 100644 index 00000000..2d0f0299 --- /dev/null +++ b/examples/omop-postgresql/README.md @@ -0,0 +1,31 @@ +# How to run datafaker process on omop schema + +## Make a YAML file representing the tables in the schema + +`poetry run datafaker make-tables --orm-file ./orm.yaml --config-file ./config.yaml` + +## Interactively set generators for column data. + +`poetry run datafaker configure-generators --orm-file ./orm.yaml --config-file ./config.yaml` + +## Compute summary statistics from the source database. + +`poetry run datafaker make-stats --orm-file ./orm.yaml --config-file ./config.yaml --stats-file ./src-stats.yaml` + +## Create schema from the ORM YAML file + +`poetry run datafaker create-tables --orm-file ./orm.yaml --config-file ./config.yaml` + +## Create generator table + +`poetry run datafaker create-generators --orm-file ./orm.yaml --config-file ./config.yaml --df-file ./df.py` + +## Create data + +`poetry run datafaker create-data --orm-file ./orm.yaml --config-file ./config.yaml --df-file ./df.py` + +## Remove data + +`poetry run datafaker remove-data --orm-file ./orm.yaml --config-file ./config.yaml` + +Plan: /Users/myong/.claude/plans/cached-rolling-snowglobe.md diff --git a/examples/omop-postgresql/config.yaml b/examples/omop-postgresql/config.yaml new file mode 100644 index 00000000..b94eef4c --- /dev/null +++ b/examples/omop-postgresql/config.yaml @@ -0,0 +1,59 @@ +src-stats: +- comments: + - All the values and their counts that appear in column ethnicity_concept_id of + table person + name: auto__person__ethnicity_concept_id + query: "SELECT _counted.value, _counted.count \nFROM (SELECT \"ethnicity_concept_id\"\ + \ AS value, count(\"ethnicity_concept_id\") AS count \nFROM mimic.person \nWHERE\ + \ \"ethnicity_concept_id\" IS NOT NULL GROUP BY \"ethnicity_concept_id\") AS _counted\ + \ ORDER BY _counted.count DESC" +- comments: + - All the values and their counts that appear in column gender_concept_id of table + person + name: auto__person__gender_concept_id + query: "SELECT _counted.value, _counted.count \nFROM (SELECT \"gender_concept_id\"\ + \ AS value, count(\"gender_concept_id\") AS count \nFROM mimic.person \nWHERE\ + \ \"gender_concept_id\" IS NOT NULL GROUP BY \"gender_concept_id\") AS _counted\ + \ ORDER BY _counted.count DESC" +- comments: + - All the values and their counts that appear in column race_concept_id of table + person + name: auto__person__race_concept_id + query: "SELECT _counted.value, _counted.count \nFROM (SELECT \"race_concept_id\"\ + \ AS value, count(\"race_concept_id\") AS count \nFROM mimic.person \nWHERE \"\ + race_concept_id\" IS NOT NULL GROUP BY \"race_concept_id\") AS _counted ORDER\ + \ BY _counted.count DESC" +- comments: + - All the values and their counts that appear in column year_of_birth of table person + name: auto__person__year_of_birth + query: "SELECT _counted.value, _counted.count \nFROM (SELECT \"year_of_birth\" AS\ + \ value, count(\"year_of_birth\") AS count \nFROM mimic.person \nWHERE \"year_of_birth\"\ + \ IS NOT NULL GROUP BY \"year_of_birth\") AS _counted ORDER BY _counted.count\ + \ DESC" +tables: + concept: + ignore: false + vocabulary_table: true + person: + num_rows_per_pass: 1 + row_generators: + - columns_assigned: + - ethnicity_concept_id + kwargs: + a: SRC_STATS["auto__person__ethnicity_concept_id"]["results"] + name: dist_gen.weighted_choice + - columns_assigned: + - gender_concept_id + kwargs: + a: SRC_STATS["auto__person__gender_concept_id"]["results"] + name: dist_gen.weighted_choice + - columns_assigned: + - race_concept_id + kwargs: + a: SRC_STATS["auto__person__race_concept_id"]["results"] + name: dist_gen.weighted_choice + - columns_assigned: + - year_of_birth + kwargs: + a: SRC_STATS["auto__person__year_of_birth"]["results"] + name: dist_gen.weighted_choice diff --git a/examples/omop-postgresql/config_template.yaml b/examples/omop-postgresql/config_template.yaml new file mode 100644 index 00000000..fe7b2653 --- /dev/null +++ b/examples/omop-postgresql/config_template.yaml @@ -0,0 +1,131 @@ +tables: + # Unnecessary tables + _measurement_links: + ignore: true + _observation_links: + ignore: true + _person_links: + ignore: true + _procedure_occurrence_links: + ignore: true + _visit_occurrence_links: + ignore: true + + # Vocab tables + concept: + # This one is a vocab, but its too big to handle the usual way + ignore: false + vocabulary_table: true + concept_ancestor: + # This one is a vocab, but its too big to handle the usual way + ignore: true + vocabulary_table: true + vocabulary: + vocabulary_table: true + domain: + vocabulary_table: true + concept_class: + vocabulary_table: true + concept_synonym: + # This one is a vocab, but its too big to handle the usual way + ignore: true + # vocabulary_table: true + concept_relationship: + # This one is a vocab, but its too big to handle the usual way + ignore: true + # vocabulary_table: true + drug_strength: + # This one is a vocab, but its too big to handle the usual way + ignore: true + # vocabulary_table: true + relationship: + vocabulary_table: true + source_to_concept_map: + vocabulary_table: true + location: + vocabulary_table: true + care_site: + vocabulary_table: true + provider: + vocabulary_table: true + cdm_source: + vocabulary_table: true + + # attribute_definition: + # num_rows_per_pass: 0 + + # cohort_definition: + # num_rows_per_pass: 0 + + # condition_era: + # num_rows_per_pass: 0 + + # cost: + # num_rows_per_pass: 0 + + # device_exposure: + # num_rows_per_pass: 0 + + # dose_era: + # num_rows_per_pass: 0 + + # drug_era: + # num_rows_per_pass: 0 + + # drug_exposure: + # num_rows_per_pass: 0 + + # fact_relationship: + # num_rows_per_pass: 0 + + # measurement: + # num_rows_per_pass: 0 + + # metadata: + # num_rows_per_pass: 0 + + # note: + # num_rows_per_pass: 0 + + # note_nlp: + # num_rows_per_pass: 0 + + # observation: + # num_rows_per_pass: 0 + + # observation_period: + # num_rows_per_pass: 0 + + # payer_plan_period: + # num_rows_per_pass: 0 + + # procedure_occurrence: + # num_rows_per_pass: 0 + # row_generators: + # - name: generic.null_provider.null + # columns_assigned: person_id + # - name: generic.column_value_provider.column_value + # columns_assigned: procedure_concept_id + # args: + # - dst_db_conn + # - metadata.tables["concept"] + # - '"concept_id"' + + + # specimen: + # num_rows_per_pass: 0 + + # visit_detail: + # num_rows_per_pass: 0 + + # visit_occurrence: + # num_rows_per_pass: 0 + + person: + num_rows_per_pass: 0 + + # death: + # num_rows_per_pass: 0 + + # condition_occurrence: + # num_rows_per_pass: 0 diff --git a/examples/omop-postgresql/df.py b/examples/omop-postgresql/df.py new file mode 100644 index 00000000..6889cf94 --- /dev/null +++ b/examples/omop-postgresql/df.py @@ -0,0 +1,88 @@ +"""This file was auto-generated by datafaker but can be edited manually.""" +from mimesis import Generic, Numeric, Person +from mimesis.locales import Locale +import sqlalchemy +import sys +from datafaker.base import FileUploader, TableGenerator, ColumnPresence +from datafaker.providers import DistributionProvider + +generic = Generic(locale=Locale.EN_GB) +numeric = Numeric() +person = Person() +dist_gen = DistributionProvider() +column_presence = ColumnPresence() + +sys.path.append("") + +from datafaker.providers import ( + BytesProvider, + ColumnValueProvider, + DistributionProvider, + NullProvider, + SQLGroupByProvider, + TimedeltaProvider, + TimespanProvider, + WeightedBooleanProvider, +) + +generic.add_provider(BytesProvider) +generic.add_provider(ColumnValueProvider) +generic.add_provider(DistributionProvider) +generic.add_provider(NullProvider) +generic.add_provider(SQLGroupByProvider) +generic.add_provider(TimedeltaProvider) +generic.add_provider(TimespanProvider) +generic.add_provider(WeightedBooleanProvider) + + +import yaml + +with open("src-stats.yaml", "r", encoding="utf-8") as f: + SRC_STATS = yaml.unsafe_load(f) + + +class PersonGenerator(TableGenerator): + num_rows_per_pass = 1 + + def __init__(self): + self.initialized = False + + def __call__(self, dst_db_conn, metadata): + if not self.initialized: + self.initialized = True + result = {} + columns_to_generate = set( + { + "ethnicity_concept_id", + "year_of_birth", + "gender_concept_id", + "race_concept_id", + } + ) + while columns_to_generate: + if "ethnicity_concept_id" in columns_to_generate: + result["ethnicity_concept_id"] = dist_gen.weighted_choice( + a=SRC_STATS["auto__person__ethnicity_concept_id"]["results"] + ) + if "gender_concept_id" in columns_to_generate: + result["gender_concept_id"] = dist_gen.weighted_choice( + a=SRC_STATS["auto__person__gender_concept_id"]["results"] + ) + if "race_concept_id" in columns_to_generate: + result["race_concept_id"] = dist_gen.weighted_choice( + a=SRC_STATS["auto__person__race_concept_id"]["results"] + ) + if "year_of_birth" in columns_to_generate: + result["year_of_birth"] = dist_gen.weighted_choice( + a=SRC_STATS["auto__person__year_of_birth"]["results"] + ) + columns_to_generate = set() + return result + + +table_generator_dict = { + "person": PersonGenerator(), +} + + +story_generator_list = [] diff --git a/examples/omop-postgresql/orm.yaml b/examples/omop-postgresql/orm.yaml new file mode 100644 index 00000000..b526fe86 --- /dev/null +++ b/examples/omop-postgresql/orm.yaml @@ -0,0 +1,127 @@ +dsn: postgresql://postgres@localhost:5432/omop5.4 +schema: mimic +tables: + concept: + columns: + concept_class_id: + foreign_keys: + - concept_class.concept_class_id + nullable: false + primary: false + type: VARCHAR(20) + concept_code: + nullable: false + primary: false + type: VARCHAR(255) + concept_id: + nullable: false + primary: true + type: BIGINT + concept_name: + nullable: false + primary: false + type: VARCHAR(255) + domain_id: + foreign_keys: + - domain.domain_id + nullable: false + primary: false + type: VARCHAR(20) + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) + standard_concept: + nullable: true + primary: false + type: VARCHAR(1) + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + vocabulary_id: + foreign_keys: + - vocabulary.vocabulary_id + nullable: false + primary: false + type: VARCHAR(50) + unique: [] + person: + columns: + # birth_datetime: + # nullable: true + # primary: false + # type: TIMESTAMP WITHOUT TIME ZONE + # day_of_birth: + # nullable: true + # primary: false + # type: BIGINT + ethnicity_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + # ethnicity_source_concept_id: + # foreign_keys: + # - concept.concept_id + # nullable: true + # primary: false + # type: BIGINT + # ethnicity_source_value: + # nullable: true + # primary: false + # type: VARCHAR(50) + gender_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + # gender_source_concept_id: + # foreign_keys: + # - concept.concept_id + # nullable: true + # primary: false + # type: BIGINT + # gender_source_value: + # nullable: true + # primary: false + # type: VARCHAR(50) + # month_of_birth: + # nullable: true + # primary: false + # type: BIGINT + person_id: + nullable: false + primary: true + type: BIGINT + # person_source_value: + # nullable: true + # primary: false + # type: VARCHAR(50) + race_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + # race_source_concept_id: + # foreign_keys: + # - concept.concept_id + # nullable: true + # primary: false + # type: BIGINT + # race_source_value: + # nullable: true + # primary: false + # type: VARCHAR(50) + year_of_birth: + nullable: false + primary: false + type: BIGINT + unique: [] diff --git a/examples/omop-postgresql/orm_full.yaml b/examples/omop-postgresql/orm_full.yaml new file mode 100644 index 00000000..a400553a --- /dev/null +++ b/examples/omop-postgresql/orm_full.yaml @@ -0,0 +1,2092 @@ +dsn: postgresql://postgres@localhost:5432/omop5.4 +schema: mimic +tables: + care_site: + columns: + care_site_id: + nullable: false + primary: true + type: BIGINT + care_site_name: + nullable: true + primary: false + type: VARCHAR(255) + care_site_source_value: + nullable: true + primary: false + type: VARCHAR(50) + location_id: + foreign_keys: + - location.location_id + nullable: true + primary: false + type: BIGINT + place_of_service_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + place_of_service_source_value: + nullable: true + primary: false + type: VARCHAR(50) + unique: [] + cdm_source: + columns: + cdm_etl_reference: + nullable: true + primary: false + type: VARCHAR(255) + cdm_holder: + nullable: false + primary: false + type: VARCHAR(255) + cdm_release_date: + nullable: false + primary: false + type: DATE + cdm_source_abbreviation: + nullable: false + primary: false + type: VARCHAR(25) + cdm_source_name: + nullable: false + primary: false + type: VARCHAR(255) + cdm_version: + nullable: true + primary: false + type: VARCHAR(10) + source_description: + nullable: true + primary: false + type: TEXT + source_documentation_reference: + nullable: true + primary: false + type: VARCHAR(255) + source_release_date: + nullable: false + primary: false + type: DATE + vocabulary_version: + nullable: false + primary: false + type: VARCHAR(20) + unique: [] + cohort: + columns: + cohort_definition_id: + nullable: false + primary: false + type: BIGINT + cohort_end_date: + nullable: false + primary: false + type: DATE + cohort_start_date: + nullable: false + primary: false + type: DATE + subject_id: + nullable: false + primary: false + type: BIGINT + unique: [] + cohort_definition: + columns: + cohort_definition_description: + nullable: true + primary: false + type: TEXT + cohort_definition_id: + nullable: false + primary: false + type: BIGINT + cohort_definition_name: + nullable: false + primary: false + type: VARCHAR(255) + cohort_definition_syntax: + nullable: true + primary: false + type: TEXT + cohort_initiation_date: + nullable: true + primary: false + type: DATE + definition_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + subject_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + unique: [] + concept: + columns: + concept_class_id: + foreign_keys: + - concept_class.concept_class_id + nullable: false + primary: false + type: VARCHAR(20) + concept_code: + nullable: false + primary: false + type: VARCHAR(255) + concept_id: + nullable: false + primary: true + type: BIGINT + concept_name: + nullable: false + primary: false + type: VARCHAR(255) + domain_id: + foreign_keys: + - domain.domain_id + nullable: false + primary: false + type: VARCHAR(20) + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) + standard_concept: + nullable: true + primary: false + type: VARCHAR(1) + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + vocabulary_id: + foreign_keys: + - vocabulary.vocabulary_id + nullable: false + primary: false + type: VARCHAR(50) + unique: [] + concept_ancestor: + columns: + ancestor_concept_id: + nullable: false + primary: false + type: BIGINT + descendant_concept_id: + nullable: false + primary: false + type: BIGINT + max_levels_of_separation: + nullable: false + primary: false + type: BIGINT + min_levels_of_separation: + nullable: false + primary: false + type: BIGINT + unique: [] + concept_class: + columns: + concept_class_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + concept_class_id: + nullable: false + primary: true + type: VARCHAR(20) + concept_class_name: + nullable: false + primary: false + type: VARCHAR(255) + unique: [] + concept_relationship: + columns: + concept_id_1: + nullable: false + primary: false + type: BIGINT + concept_id_2: + nullable: false + primary: false + type: BIGINT + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) + relationship_id: + foreign_keys: + - relationship.relationship_id + nullable: false + primary: false + type: VARCHAR(20) + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + unique: [] + concept_synonym: + columns: + concept_id: + nullable: false + primary: false + type: BIGINT + concept_synonym_name: + nullable: false + primary: false + type: VARCHAR(1000) + language_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + unique: [] + condition_era: + columns: + condition_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + condition_era_end_date: + nullable: false + primary: false + type: DATE + condition_era_id: + nullable: false + primary: true + type: BIGINT + condition_era_start_date: + nullable: false + primary: false + type: DATE + condition_occurrence_count: + nullable: true + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + unique: [] + condition_occurrence: + columns: + condition_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + condition_end_date: + nullable: true + primary: false + type: DATE + condition_end_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + condition_occurrence_id: + nullable: false + primary: true + type: BIGINT + condition_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + condition_source_value: + nullable: true + primary: false + type: VARCHAR(50) + condition_start_date: + nullable: false + primary: false + type: DATE + condition_start_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + condition_status_concept_id: + nullable: true + primary: false + type: VARCHAR(50) + condition_status_source_value: + nullable: true + primary: false + type: VARCHAR(50) + condition_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + stop_reason: + nullable: true + primary: false + type: VARCHAR(20) + visit_detail_id: + foreign_keys: + - visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + cost: + columns: + amount_allowed: + nullable: true + primary: false + type: NUMERIC + cost_domain_id: + foreign_keys: + - domain.domain_id + nullable: false + primary: false + type: VARCHAR(20) + cost_event_id: + nullable: false + primary: false + type: BIGINT + cost_id: + nullable: false + primary: true + type: BIGINT + cost_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + currency_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + drg_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + drg_source_value: + nullable: true + primary: false + type: VARCHAR(3) + paid_by_patient: + nullable: true + primary: false + type: NUMERIC + paid_by_payer: + nullable: true + primary: false + type: NUMERIC + paid_by_primary: + nullable: true + primary: false + type: NUMERIC + paid_dispensing_fee: + nullable: true + primary: false + type: NUMERIC + paid_ingredient_cost: + nullable: true + primary: false + type: NUMERIC + paid_patient_coinsurance: + nullable: true + primary: false + type: NUMERIC + paid_patient_copay: + nullable: true + primary: false + type: NUMERIC + paid_patient_deductible: + nullable: true + primary: false + type: NUMERIC + payer_plan_period_id: + nullable: true + primary: false + type: BIGINT + revenue_code_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + revenue_code_source_value: + nullable: true + primary: false + type: VARCHAR(50) + total_charge: + nullable: true + primary: false + type: NUMERIC + total_cost: + nullable: true + primary: false + type: NUMERIC + total_paid: + nullable: true + primary: false + type: NUMERIC + unique: [] + death: + columns: + cause_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + cause_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + cause_source_value: + nullable: true + primary: false + type: VARCHAR(50) + death_date: + nullable: false + primary: false + type: DATE + death_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + death_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + unique: [] + device_exposure: + columns: + device_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + device_exposure_end_date: + nullable: true + primary: false + type: DATE + device_exposure_end_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + device_exposure_id: + nullable: false + primary: true + type: BIGINT + device_exposure_start_date: + nullable: false + primary: false + type: DATE + device_exposure_start_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + device_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + device_source_value: + nullable: true + primary: false + type: VARCHAR(50) + device_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + quantity: + nullable: true + primary: false + type: BIGINT + unique_device_id: + nullable: true + primary: false + type: VARCHAR(255) + visit_detail_id: + foreign_keys: + - visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + domain: + columns: + domain_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + domain_id: + nullable: false + primary: true + type: VARCHAR(20) + domain_name: + nullable: false + primary: false + type: VARCHAR(255) + unique: [] + dose_era: + columns: + dose_era_end_date: + nullable: false + primary: false + type: DATE + dose_era_id: + nullable: false + primary: true + type: BIGINT + dose_era_start_date: + nullable: false + primary: false + type: DATE + dose_value: + nullable: false + primary: false + type: NUMERIC + drug_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + unit_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + unique: [] + drug_era: + columns: + drug_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + drug_era_end_date: + nullable: false + primary: false + type: DATE + drug_era_id: + nullable: false + primary: true + type: BIGINT + drug_era_start_date: + nullable: false + primary: false + type: DATE + drug_exposure_count: + nullable: true + primary: false + type: BIGINT + gap_days: + nullable: true + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + unique: [] + drug_exposure: + columns: + days_supply: + nullable: true + primary: false + type: BIGINT + dose_unit_source_value: + nullable: true + primary: false + type: VARCHAR(50) + drug_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + drug_exposure_end_date: + nullable: false + primary: false + type: DATE + drug_exposure_end_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + drug_exposure_id: + nullable: false + primary: true + type: BIGINT + drug_exposure_start_date: + nullable: false + primary: false + type: DATE + drug_exposure_start_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + drug_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + drug_source_value: + nullable: true + primary: false + type: VARCHAR(255) + drug_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + lot_number: + nullable: true + primary: false + type: VARCHAR(50) + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + quantity: + nullable: true + primary: false + type: NUMERIC + refills: + nullable: true + primary: false + type: BIGINT + route_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + route_source_value: + nullable: true + primary: false + type: VARCHAR(50) + sig: + nullable: true + primary: false + type: TEXT + stop_reason: + nullable: true + primary: false + type: VARCHAR(20) + verbatim_end_date: + nullable: true + primary: false + type: DATE + visit_detail_id: + foreign_keys: + - visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + drug_strength: + columns: + amount_unit_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + amount_value: + nullable: true + primary: false + type: NUMERIC + box_size: + nullable: true + primary: false + type: BIGINT + denominator_unit_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + denominator_value: + nullable: true + primary: false + type: NUMERIC + drug_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + ingredient_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) + numerator_unit_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + numerator_value: + nullable: true + primary: false + type: NUMERIC + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + unique: [] + episode: + columns: + episode_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + episode_end_date: + nullable: true + primary: false + type: DATE + episode_end_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + episode_id: + nullable: false + primary: true + type: BIGINT + episode_number: + nullable: true + primary: false + type: BIGINT + episode_object_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + episode_parent_id: + nullable: true + primary: false + type: BIGINT + episode_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + episode_source_value: + nullable: true + primary: false + type: VARCHAR(50) + episode_start_date: + nullable: false + primary: false + type: DATE + episode_start_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + episode_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + unique: [] + episode_event: + columns: + episode_event_field_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + episode_id: + foreign_keys: + - episode.episode_id + nullable: false + primary: false + type: BIGINT + event_id: + nullable: false + primary: false + type: BIGINT + unique: [] + fact_relationship: + columns: + domain_concept_id_1: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + domain_concept_id_2: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + fact_id_1: + nullable: false + primary: false + type: BIGINT + fact_id_2: + nullable: false + primary: false + type: BIGINT + relationship_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + unique: [] + location: + columns: + address_1: + nullable: true + primary: false + type: VARCHAR(50) + address_2: + nullable: true + primary: false + type: VARCHAR(50) + city: + nullable: true + primary: false + type: VARCHAR(50) + county: + nullable: true + primary: false + type: VARCHAR(20) + location_id: + nullable: false + primary: true + type: BIGINT + location_source_value: + nullable: true + primary: false + type: VARCHAR(50) + state: + nullable: true + primary: false + type: VARCHAR(2) + zip: + nullable: true + primary: false + type: VARCHAR(9) + unique: [] + measurement: + columns: + measurement_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + measurement_date: + nullable: false + primary: false + type: DATE + measurement_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + measurement_id: + nullable: false + primary: true + type: BIGINT + measurement_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + measurement_source_value: + nullable: true + primary: false + type: VARCHAR(50) + measurement_time: + nullable: true + primary: false + type: VARCHAR(10) + measurement_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + operator_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + range_high: + nullable: true + primary: false + type: NUMERIC + range_low: + nullable: true + primary: false + type: NUMERIC + unit_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + unit_source_value: + nullable: true + primary: false + type: VARCHAR(50) + value_as_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + value_as_number: + nullable: true + primary: false + type: NUMERIC + value_source_value: + nullable: true + primary: false + type: VARCHAR(50) + visit_detail_id: + foreign_keys: + - visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + metadata: + columns: + metadata_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + metadata_date: + nullable: true + primary: false + type: DATE + metadata_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + metadata_id: + nullable: false + primary: true + type: BIGINT + metadata_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + name: + nullable: false + primary: false + type: VARCHAR(250) + value_as_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + value_as_number: + nullable: true + primary: false + type: NUMERIC + value_as_string: + nullable: true + primary: false + type: VARCHAR(250) + unique: [] + note: + columns: + encoding_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + language_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + note_class_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + note_date: + nullable: false + primary: false + type: DATE + note_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + note_event_field_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + note_event_id: + nullable: true + primary: false + type: BIGINT + note_id: + nullable: false + primary: true + type: BIGINT + note_source_value: + nullable: true + primary: false + type: VARCHAR(50) + note_text: + nullable: false + primary: false + type: TEXT + note_title: + nullable: true + primary: false + type: VARCHAR(250) + note_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + visit_detail_id: + foreign_keys: + - visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + note_nlp: + columns: + lexical_variant: + nullable: false + primary: false + type: VARCHAR(250) + nlp_date: + nullable: false + primary: false + type: DATE + nlp_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + nlp_system: + nullable: true + primary: false + type: VARCHAR(250) + note_id: + nullable: false + primary: false + type: BIGINT + note_nlp_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + note_nlp_id: + nullable: false + primary: true + type: BIGINT + note_nlp_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + offset: + nullable: true + primary: false + type: VARCHAR(50) + section_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + snippet: + nullable: true + primary: false + type: VARCHAR(250) + term_exists: + nullable: true + primary: false + type: VARCHAR(1) + term_modifiers: + nullable: true + primary: false + type: VARCHAR(2000) + term_temporal: + nullable: true + primary: false + type: VARCHAR(50) + unique: [] + observation: + columns: + observation_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + observation_date: + nullable: false + primary: false + type: DATE + observation_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + observation_id: + nullable: false + primary: true + type: BIGINT + observation_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + observation_source_value: + nullable: true + primary: false + type: VARCHAR(50) + observation_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + qualifier_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + qualifier_source_value: + nullable: true + primary: false + type: VARCHAR(50) + unit_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + unit_source_value: + nullable: true + primary: false + type: VARCHAR(50) + value_as_concept_id: + nullable: true + primary: false + type: BIGINT + value_as_number: + nullable: true + primary: false + type: NUMERIC + value_as_string: + nullable: true + primary: false + type: VARCHAR(120) + visit_detail_id: + foreign_keys: + - visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + observation_period: + columns: + observation_period_end_date: + nullable: false + primary: false + type: DATE + observation_period_id: + nullable: false + primary: true + type: BIGINT + observation_period_start_date: + nullable: false + primary: false + type: DATE + period_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + unique: [] + payer_plan_period: + columns: + family_source_value: + nullable: true + primary: false + type: VARCHAR(50) + payer_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + payer_plan_period_end_date: + nullable: false + primary: false + type: DATE + payer_plan_period_id: + nullable: false + primary: true + type: BIGINT + payer_plan_period_start_date: + nullable: false + primary: false + type: DATE + payer_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + payer_source_value: + nullable: true + primary: false + type: VARCHAR(50) + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + plan_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + plan_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + plan_source_value: + nullable: true + primary: false + type: VARCHAR(50) + sponsor_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + sponsor_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + sponsor_source_value: + nullable: true + primary: false + type: VARCHAR(50) + stop_reason_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + stop_reason_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + stop_reason_source_value: + nullable: true + primary: false + type: VARCHAR(50) + unique: [] + person: + columns: + birth_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + care_site_id: + foreign_keys: + - care_site.care_site_id + nullable: true + primary: false + type: BIGINT + day_of_birth: + nullable: true + primary: false + type: BIGINT + ethnicity_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + ethnicity_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + ethnicity_source_value: + nullable: true + primary: false + type: VARCHAR(50) + gender_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + gender_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + gender_source_value: + nullable: true + primary: false + type: VARCHAR(50) + location_id: + foreign_keys: + - location.location_id + nullable: true + primary: false + type: BIGINT + month_of_birth: + nullable: true + primary: false + type: BIGINT + person_id: + nullable: false + primary: true + type: BIGINT + person_source_value: + nullable: true + primary: false + type: VARCHAR(50) + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + race_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + race_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + race_source_value: + nullable: true + primary: false + type: VARCHAR(50) + year_of_birth: + nullable: false + primary: false + type: BIGINT + unique: [] + procedure_occurrence: + columns: + modifier_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + modifier_source_value: + nullable: true + primary: false + type: VARCHAR(50) + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + procedure_concept_id: + nullable: false + primary: false + type: BIGINT + procedure_date: + nullable: false + primary: false + type: DATE + procedure_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + procedure_occurrence_id: + nullable: false + primary: true + type: BIGINT + procedure_source_concept_id: + nullable: true + primary: false + type: BIGINT + procedure_source_value: + nullable: true + primary: false + type: VARCHAR(50) + procedure_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + quantity: + nullable: true + primary: false + type: BIGINT + visit_detail_id: + foreign_keys: + - visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + unique: [] + provider: + columns: + care_site_id: + foreign_keys: + - care_site.care_site_id + nullable: true + primary: false + type: BIGINT + dea: + nullable: true + primary: false + type: VARCHAR(20) + gender_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + gender_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + gender_source_value: + nullable: true + primary: false + type: VARCHAR(50) + npi: + nullable: true + primary: false + type: VARCHAR(20) + provider_id: + nullable: false + primary: true + type: BIGINT + provider_name: + nullable: true + primary: false + type: VARCHAR(255) + provider_source_value: + nullable: true + primary: false + type: VARCHAR(50) + specialty_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + specialty_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + specialty_source_value: + nullable: true + primary: false + type: VARCHAR(50) + year_of_birth: + nullable: true + primary: false + type: BIGINT + unique: [] + relationship: + columns: + defines_ancestry: + nullable: false + primary: false + type: VARCHAR(1) + is_hierarchical: + nullable: false + primary: false + type: VARCHAR(1) + relationship_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + relationship_id: + nullable: false + primary: true + type: VARCHAR(20) + relationship_name: + nullable: false + primary: false + type: VARCHAR(255) + reverse_relationship_id: + nullable: false + primary: false + type: VARCHAR(20) + unique: [] + source_to_concept_map: + columns: + invalid_reason: + nullable: true + primary: false + type: VARCHAR(1) + source_code: + nullable: false + primary: false + type: VARCHAR(50) + source_code_description: + nullable: true + primary: false + type: VARCHAR(255) + source_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + source_vocabulary_id: + nullable: false + primary: false + type: VARCHAR(20) + target_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + target_vocabulary_id: + foreign_keys: + - vocabulary.vocabulary_id + nullable: false + primary: false + type: VARCHAR(20) + valid_end_date: + nullable: false + primary: false + type: DATE + valid_start_date: + nullable: false + primary: false + type: DATE + unique: [] + specimen: + columns: + anatomic_site_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + anatomic_site_source_value: + nullable: true + primary: false + type: VARCHAR(50) + disease_status_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + disease_status_source_value: + nullable: true + primary: false + type: VARCHAR(50) + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + quantity: + nullable: true + primary: false + type: NUMERIC + specimen_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + specimen_date: + nullable: false + primary: false + type: DATE + specimen_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + specimen_id: + nullable: false + primary: true + type: BIGINT + specimen_source_id: + nullable: true + primary: false + type: VARCHAR(255) + specimen_source_value: + nullable: true + primary: false + type: VARCHAR(50) + specimen_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + unit_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + unit_source_value: + nullable: true + primary: false + type: VARCHAR(50) + unique: [] + visit_detail: + columns: + admitting_source_concept_id: + nullable: true + primary: false + type: BIGINT + admitting_source_value: + nullable: true + primary: false + type: VARCHAR(50) + care_site_id: + foreign_keys: + - care_site.care_site_id + nullable: true + primary: false + type: BIGINT + discharge_to_concept_id: + nullable: true + primary: false + type: BIGINT + discharge_to_source_value: + nullable: true + primary: false + type: VARCHAR(50) + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + preceding_visit_detail_id: + foreign_keys: + - visit_detail.visit_detail_id + nullable: true + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + visit_detail_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + visit_detail_end_date: + nullable: false + primary: false + type: DATE + visit_detail_end_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + visit_detail_id: + nullable: false + primary: true + type: BIGINT + visit_detail_parent_id: + nullable: true + primary: false + type: VARCHAR(50) + visit_detail_source_concept_id: + nullable: true + primary: false + type: VARCHAR(50) + visit_detail_source_value: + nullable: true + primary: false + type: VARCHAR(120) + visit_detail_start_date: + nullable: false + primary: false + type: DATE + visit_detail_start_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + visit_detail_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: false + primary: false + type: BIGINT + unique: [] + visit_occurrence: + columns: + admitted_from_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + admitted_from_source_value: + nullable: true + primary: false + type: VARCHAR(50) + care_site_id: + foreign_keys: + - care_site.care_site_id + nullable: true + primary: false + type: BIGINT + discharged_to_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + discharged_to_source_value: + nullable: true + primary: false + type: VARCHAR(50) + person_id: + foreign_keys: + - person.person_id + nullable: false + primary: false + type: BIGINT + preceding_visit_occurrence_id: + foreign_keys: + - visit_occurrence.visit_occurrence_id + nullable: true + primary: false + type: BIGINT + provider_id: + foreign_keys: + - provider.provider_id + nullable: true + primary: false + type: BIGINT + visit_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + visit_end_date: + nullable: false + primary: false + type: DATE + visit_end_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + visit_occurrence_id: + nullable: false + primary: true + type: BIGINT + visit_source_concept_id: + foreign_keys: + - concept.concept_id + nullable: true + primary: false + type: BIGINT + visit_source_value: + nullable: true + primary: false + type: VARCHAR(50) + visit_start_date: + nullable: false + primary: false + type: DATE + visit_start_datetime: + nullable: true + primary: false + type: TIMESTAMP WITHOUT TIME ZONE + visit_type_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + unique: [] + vocabulary: + columns: + vocabulary_concept_id: + foreign_keys: + - concept.concept_id + nullable: false + primary: false + type: BIGINT + vocabulary_id: + nullable: false + primary: true + type: VARCHAR(30) + vocabulary_name: + nullable: false + primary: false + type: VARCHAR(255) + vocabulary_reference: + nullable: true + primary: false + type: VARCHAR(255) + vocabulary_version: + nullable: true + primary: false + type: VARCHAR(255) + unique: [] diff --git a/examples/omop-postgresql/src-stats.yaml b/examples/omop-postgresql/src-stats.yaml new file mode 100644 index 00000000..1f9fde32 --- /dev/null +++ b/examples/omop-postgresql/src-stats.yaml @@ -0,0 +1,193 @@ +auto__person__ethnicity_concept_id: + comments: + - All the values and their counts that appear in column ethnicity_concept_id of + table person + queries: + date: '2026-05-22 15:39:07' + query: "SELECT _counted.value, _counted.count \nFROM (SELECT \"ethnicity_concept_id\"\ + \ AS value, count(\"ethnicity_concept_id\") AS count \nFROM mimic.person \n\ + WHERE \"ethnicity_concept_id\" IS NOT NULL GROUP BY \"ethnicity_concept_id\"\ + ) AS _counted ORDER BY _counted.count DESC" + results: + - count: 95 + value: 0 + - count: 5 + value: 38003563 +auto__person__gender_concept_id: + comments: + - All the values and their counts that appear in column gender_concept_id of table + person + queries: + date: '2026-05-22 15:39:07' + query: "SELECT _counted.value, _counted.count \nFROM (SELECT \"gender_concept_id\"\ + \ AS value, count(\"gender_concept_id\") AS count \nFROM mimic.person \nWHERE\ + \ \"gender_concept_id\" IS NOT NULL GROUP BY \"gender_concept_id\") AS _counted\ + \ ORDER BY _counted.count DESC" + results: + - count: 57 + value: 8507 + - count: 43 + value: 8532 +auto__person__race_concept_id: + comments: + - All the values and their counts that appear in column race_concept_id of table + person + queries: + date: '2026-05-22 15:39:07' + query: "SELECT _counted.value, _counted.count \nFROM (SELECT \"race_concept_id\"\ + \ AS value, count(\"race_concept_id\") AS count \nFROM mimic.person \nWHERE\ + \ \"race_concept_id\" IS NOT NULL GROUP BY \"race_concept_id\") AS _counted\ + \ ORDER BY _counted.count DESC" + results: + - count: 64 + value: 8527 + - count: 13 + value: 2000001401 + - count: 10 + value: 8516 + - count: 5 + value: 0 + - count: 5 + value: 2000001402 + - count: 3 + value: 2000001405 +auto__person__year_of_birth: + comments: + - All the values and their counts that appear in column year_of_birth of table person + queries: + date: '2026-05-22 15:39:07' + query: "SELECT _counted.value, _counted.count \nFROM (SELECT \"year_of_birth\"\ + \ AS value, count(\"year_of_birth\") AS count \nFROM mimic.person \nWHERE \"\ + year_of_birth\" IS NOT NULL GROUP BY \"year_of_birth\") AS _counted ORDER BY\ + \ _counted.count DESC" + results: + - count: 4 + value: 2062 + - count: 3 + value: 2070 + - count: 3 + value: 2058 + - count: 3 + value: 2073 + - count: 3 + value: 2119 + - count: 3 + value: 2084 + - count: 3 + value: 2059 + - count: 2 + value: 2125 + - count: 2 + value: 2094 + - count: 2 + value: 2136 + - count: 2 + value: 2083 + - count: 2 + value: 2052 + - count: 2 + value: 2106 + - count: 2 + value: 2123 + - count: 2 + value: 2066 + - count: 2 + value: 2104 + - count: 2 + value: 2089 + - count: 2 + value: 2102 + - count: 2 + value: 2075 + - count: 2 + value: 2043 + - count: 2 + value: 2079 + - count: 2 + value: 2050 + - count: 2 + value: 2133 + - count: 2 + value: 2055 + - count: 2 + value: 2086 + - count: 2 + value: 2085 + - count: 2 + value: 2130 + - count: 1 + value: 2033 + - count: 1 + value: 2031 + - count: 1 + value: 2117 + - count: 1 + value: 2122 + - count: 1 + value: 2099 + - count: 1 + value: 2069 + - count: 1 + value: 2149 + - count: 1 + value: 2095 + - count: 1 + value: 2092 + - count: 1 + value: 2071 + - count: 1 + value: 2145 + - count: 1 + value: 2049 + - count: 1 + value: 2030 + - count: 1 + value: 2128 + - count: 1 + value: 2074 + - count: 1 + value: 2114 + - count: 1 + value: 2108 + - count: 1 + value: 2060 + - count: 1 + value: 2097 + - count: 1 + value: 2116 + - count: 1 + value: 2064 + - count: 1 + value: 2090 + - count: 1 + value: 2038 + - count: 1 + value: 2077 + - count: 1 + value: 2103 + - count: 1 + value: 2041 + - count: 1 + value: 2138 + - count: 1 + value: 2096 + - count: 1 + value: 2093 + - count: 1 + value: 2061 + - count: 1 + value: 2118 + - count: 1 + value: 2120 + - count: 1 + value: 2111 + - count: 1 + value: 2067 + - count: 1 + value: 2134 + - count: 1 + value: 2105 + - count: 1 + value: 2115 + - count: 1 + value: 2054 diff --git a/poetry.lock b/poetry.lock index a1a73566..9c4261fb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,19 @@ # This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +[[package]] +name = "aioodbc" +version = "0.5.0" +description = "ODBC driver for asyncio." +optional = false +python-versions = ">=3.7" +files = [ + {file = "aioodbc-0.5.0-py3-none-any.whl", hash = "sha256:bcaf16f007855fa4bf0ce6754b1f72c6c5a3d544188849577ddd55c5dc42985e"}, + {file = "aioodbc-0.5.0.tar.gz", hash = "sha256:cbccd89ce595c033a49c9e6b4b55bbace7613a104b8a46e3d4c58c4bc4f25075"}, +] + +[package.dependencies] +pyodbc = ">=5.0.1" + [[package]] name = "alabaster" version = "0.7.16" @@ -34,44 +48,45 @@ files = [ [[package]] name = "ast-serialize" -version = "0.5.0" +version = "0.6.0" description = "Python bindings for mypy AST serialization" optional = false python-versions = ">=3.7" files = [ - {file = "ast_serialize-0.5.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-win32.whl", hash = "sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb"}, - {file = "ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101"}, - {file = "ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934"}, - {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759"}, - {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887"}, - {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27"}, - {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d"}, - {file = "ast_serialize-0.5.0-cp39-abi3-win32.whl", hash = "sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a"}, - {file = "ast_serialize-0.5.0-cp39-abi3-win_amd64.whl", hash = "sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590"}, - {file = "ast_serialize-0.5.0-cp39-abi3-win_arm64.whl", hash = "sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642"}, - {file = "ast_serialize-0.5.0.tar.gz", hash = "sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:a7520b672827885bafeae7501f684d14d47d17e5f45256f9df547686cca52264"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a14191beec7e0c078d2fc1f6edc0aee88bcd4db9f18e1bc9f8052b559c22dddc"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32ef62ec34cf6be20ad77d4799556638fbdf187f3ae10698dfb20ef9f2c89516"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13b7769970a39983b0adf2f38917b1cd3b8946f76df045756c3d741bc689f089"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f7a408601bb3edaefb3bc67a4c01f5235e3253653b6a5729a2ee2382b35341c"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8670bfa51208a2c0c8d138928e40e998fab158f9200d53bb80c088b5b8eda7b8"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4826809eb8597a8cd59fd924b6d7c285b8969a1e0007e2cb652cab62376270f"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:577a6c189068686869f5f1ddc38363f3ae1808a4753b577266f9202071a7bb66"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:085de7f62dc9cc247eb01e965a362707d1d90b1d89a82c5bf78301a60a3c417b"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9f8a8b78b13173de6a9ec22111d9be674874cd5bdccda04f14ae5ebc2bef403a"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f2ff3baffc3a29c1f15bc9098aa0c09763410262d5e6cef42116f7356c184554"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0067b25fce104eaae5b88383de9ab803faeb671831e14ca698b771b356e2600f"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c617417f9cbb0cb144f6283c3cbe0d2e0f01beaf9f608f662b21191058a626ec"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-win32.whl", hash = "sha256:5337cb256dcea3df9288205213d1601581536526b8f4da44b6974f1180f3252a"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2d947e45cafc4b09bd7528917fa84c517654a43de173c79785574b7b3068ac24"}, + {file = "ast_serialize-0.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:6e15ec740436e1a0d62de848641abe5f3a2f89a7f94907d534795ac91bbacf14"}, + {file = "ast_serialize-0.6.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:093cb8bb91b720d8523580498d031791bb1bbaa048599c3d21085d380e11a596"}, + {file = "ast_serialize-0.6.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:e61580a69faf47e3689795367ed211f2a10fd741478cc0f36a0f128793360aad"}, + {file = "ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305802f2ce2a7c4e87835078ea85c58b586ddda8095b92fe2ead9364ae19c80a"}, + {file = "ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c7b8b8f0c42f752ea00b2b7d7c090b3f80d9c1c5c75cadf16423790a0cc74081"}, + {file = "ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd5b91b9e6f2356ace3a556963b0cd783b395fbbb0bb17b4defc283415466e77"}, + {file = "ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d6ef91590258ada18909b9caea344dac4de2013906b035473cd674a43f4b790"}, + {file = "ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcbed41e9386059fc0261d602445ede0976c2ecec2939688bcbcb9ed0b6f28b7"}, + {file = "ast_serialize-0.6.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:cdc4e6f930b9090c2f92c9036ad12ffb8e6e44d4a5ba06f1458a05d60f203f7b"}, + {file = "ast_serialize-0.6.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:897ac47b5637be41c0c07061c8a912fafa967ef1dc73fa115e4bfa70882a093b"}, + {file = "ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c4af9a1386166e40ed01464991806f89038a2d89782576c7774876fa77034e32"}, + {file = "ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:c901adbd750029b9ac4ad3d6aa56853e0ad4875119fbf52b7b8298afc223828b"}, + {file = "ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:3ae22a366b752ab4496191525b78b097b5b72d531752e3c1dd7e383a8f2c8a1a"}, + {file = "ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4ed29121da8b3fdc291002801a1de0f76248fa07dce89157a5f277842cf6126e"}, + {file = "ast_serialize-0.6.0-cp39-abi3-pyemscripten_2026_0_wasm32.whl", hash = "sha256:b1dac4e09d341c1300ba69cdcbe62867b32a8c75d90db9bf4d083bec3b039f0b"}, + {file = "ast_serialize-0.6.0-cp39-abi3-win32.whl", hash = "sha256:82c312a7844d2fdeb4d5c48bd3d215bf940dafd4704e1a9bcf252a99010a99b1"}, + {file = "ast_serialize-0.6.0-cp39-abi3-win_amd64.whl", hash = "sha256:113b58346f9ceb664352032770caca817d4a3c86f611c6088e6ef65ddaa70f0e"}, + {file = "ast_serialize-0.6.0-cp39-abi3-win_arm64.whl", hash = "sha256:ccd132fe8db56f61fe743b1f644d01b8d65b83248a8da506f3132bda86d6ed5e"}, + {file = "ast_serialize-0.6.0.tar.gz", hash = "sha256:aadd3ffcf4858c9726bf3515f7b199c7eadbe504f96028e4a87172c0da65a8fe"}, ] [[package]] @@ -238,13 +253,13 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2026.4.22" +version = "2026.7.22" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" files = [ - {file = "certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a"}, - {file = "certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580"}, + {file = "certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775"}, + {file = "certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55"}, ] [[package]] @@ -260,140 +275,104 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.7" +version = "3.4.9" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943"}, - {file = "charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00"}, - {file = "charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6"}, - {file = "charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110"}, - {file = "charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f"}, - {file = "charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c"}, - {file = "charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux_2_31_armv7l.whl", hash = "sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-win32.whl", hash = "sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207"}, - {file = "charset_normalizer-3.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-win32.whl", hash = "sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444"}, - {file = "charset_normalizer-3.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c"}, - {file = "charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d"}, - {file = "charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c1225416b463483160e4af85d5fc3a9690ccb53fd4b1865a6437825f5ede3209"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d10d789dd9bcca1173c95af82c58433122564b7bc39385124be735a35cbe99"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bb41182d93ea91f60b4bc8fbf4c820c69ef8a12ab2d917f3f1834f1acad07e8"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:bcf74c1df76758a395bf0af608c04c82257523f55c9868b334f06270d0f2112b"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b5314963fce9b0b12743891de876e724997864ee22aa496f903f426c7e2fa5b2"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e9701d0049d92c16703a42771b98d560b95248949f23f8cf7b4eddd201814fb9"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:65a7ff3f705e57d392f7261b6d0550fe137c3019477431f1c355e0db0a7d3e15"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79580094b00d1789d1f93ea55bc43cb2f611910c72235b7657f3482ddcc1b22d"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-win32.whl", hash = "sha256:432786d3561e69aeeae6c7e8648964ce0ad05736120135601f87ac26b9c83381"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:8c041122946b7ba21bb32c45b1aa57b1be35527690aeb3c5c234521085632eee"}, + {file = "charset_normalizer-3.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:375b83ed0aecfce76c16d198fbc21f3b11b337d68662bea0a995046682a11419"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0e94703ec9684807f20cfb5eed95c70f67f2a8f21ad620146d7b5a13677b93e5"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a441ea71902098ffe78c5abe6c494f44160b4af614ed16c3d9a3b1d17fd8ee2"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:304b13570067b2547562e308af560b3963857b1fa90bd6afd978130130fe2d6a"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4773092f8019072343a7447203308b176e10199920eb02d6195e81bbb3274c29"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04ce310cb89c15df659582aee80a0603788732a5e017d5bd5c81158106ce249c"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:c0323c9daef75ef2e5083624b4585018a0c9d5e3b40f607eed81a311270b934b"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:871ff67ea1aad4dfd91736464934d56b32dac49f9fbe16cddba36198a7b3a0db"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:67830fc78e67501f47bb950471b2dcb9b35b140084429318e862895a8e89c993"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3d92613ec25e43b05f042302531ec0f00b8445190e43325880cbd6ab7c2581da"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:280081916dc341820640489a66e4696049401ef1cf6dd672f672e70ad915aca3"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-win32.whl", hash = "sha256:ac351b3b8014eead140e77e9717e2992c6bbe30b63bc3422422eb84865412e3d"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:6366a16e1a25018694d6a5d784d09b046edc9eac40ea2b54065c3052672516a1"}, + {file = "charset_normalizer-3.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:1d22856ffbe153a602df38e4a5464f0b748a54002e0d69ac6d2ad0a197cc99ec"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-win32.whl", hash = "sha256:78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0"}, + {file = "charset_normalizer-3.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-win32.whl", hash = "sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115"}, + {file = "charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-win32.whl", hash = "sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b"}, + {file = "charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-win32.whl", hash = "sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177"}, + {file = "charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:253a4a220747e8b5faf57ec320c4f5efb0cef05f647420bf267143ec15dba10a"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68ce9f4d6b26d5ccbf7fd4459bf75f74a0a146677ebba80597df60cbdb20e6f4"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:58150c9f9b9a552505912d182ccdf26f6396fb6094816ceebcbb20eecabaed94"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df7276909358e5635ae203673ab7e509ddd224225a8d6b0790bf13eb2bde1cc5"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c09a49d6cde137258beb3d551994a2927fd35ad5cf96aed573f61bbd67c5f84"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:231ddcbb35e2ff8973e1365db41fe0572662893b99a05deb183b68ad4c0c8bd4"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:920079c3f7456fa213e0829ed2073aaa727fd39d889ead5b4f35d0de5460d04f"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0fa1aec2d32bcc03c8fa0f6f1712caad1adc38509f31142112e5c9daf5b9c833"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ad41ba96094304aa090f5a30cb6e4fb3b3f1c264c523394b4c39bbacc4dc92ba"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:43b9e366a31fdd1c87d0eb08f579b4a82b723ea54338f040d6b4e518a026ea29"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-win32.whl", hash = "sha256:93d59d504b230e83c7a843251681959a0b6a9cd76f6e146ce1b8a80eb8739af9"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-win_amd64.whl", hash = "sha256:ddf4af30b417d9fe16481e9b81c27ab2a7cde1ff7ba3e85653b02db7d145dc7b"}, + {file = "charset_normalizer-3.4.9-cp39-cp39-win_arm64.whl", hash = "sha256:476743fe6dfe14a2da12e3ac79125dc84a3b2cf8094369a47a1529b0cd8549fe"}, + {file = "charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5"}, + {file = "charset_normalizer-3.4.9.tar.gz", hash = "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b"}, ] [[package]] @@ -615,13 +594,13 @@ profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "distlib" -version = "0.4.0" +version = "0.4.3" description = "Distribution utilities" optional = false python-versions = "*" files = [ - {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, - {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, + {file = "distlib-0.4.3-py2.py3-none-any.whl", hash = "sha256:4b0ce306c966eb73bc3a7b6abad017c556dadd92c44701562cd528ac7fde4d5b"}, + {file = "distlib-0.4.3.tar.gz", hash = "sha256:f152097224a0ae24be5a0f6bae1b9359af82133bce63f98a95f86cae1aede9ed"}, ] [[package]] @@ -637,46 +616,46 @@ files = [ [[package]] name = "duckdb" -version = "1.5.2" +version = "1.5.5" description = "DuckDB in-process database" optional = false python-versions = ">=3.10.0" files = [ - {file = "duckdb-1.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1"}, - {file = "duckdb-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db"}, - {file = "duckdb-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53"}, - {file = "duckdb-1.5.2-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08"}, - {file = "duckdb-1.5.2-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536"}, - {file = "duckdb-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1"}, - {file = "duckdb-1.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d"}, - {file = "duckdb-1.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3"}, - {file = "duckdb-1.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8"}, - {file = "duckdb-1.5.2-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d"}, - {file = "duckdb-1.5.2-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2"}, - {file = "duckdb-1.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9"}, - {file = "duckdb-1.5.2-cp311-cp311-win_arm64.whl", hash = "sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f"}, - {file = "duckdb-1.5.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1"}, - {file = "duckdb-1.5.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e"}, - {file = "duckdb-1.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed"}, - {file = "duckdb-1.5.2-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1"}, - {file = "duckdb-1.5.2-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855"}, - {file = "duckdb-1.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83"}, - {file = "duckdb-1.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00"}, - {file = "duckdb-1.5.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79"}, - {file = "duckdb-1.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed"}, - {file = "duckdb-1.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6"}, - {file = "duckdb-1.5.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39"}, - {file = "duckdb-1.5.2-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7"}, - {file = "duckdb-1.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b"}, - {file = "duckdb-1.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d"}, - {file = "duckdb-1.5.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785"}, - {file = "duckdb-1.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec"}, - {file = "duckdb-1.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160"}, - {file = "duckdb-1.5.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2"}, - {file = "duckdb-1.5.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a"}, - {file = "duckdb-1.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4"}, - {file = "duckdb-1.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31"}, - {file = "duckdb-1.5.2.tar.gz", hash = "sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246"}, + {file = "duckdb-1.5.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3b805507f88171b428b21c966c30e9a3d54e30b24528918a44ed0032542bc26f"}, + {file = "duckdb-1.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b08e19cc856220d8a26fa62abc2264b349aff67255e9373c6a3f607addd56dc6"}, + {file = "duckdb-1.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a17e6a922e42a5c06ed2353fe78c5dff2610f6632d603836f9606ad0bf754079"}, + {file = "duckdb-1.5.5-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bdc38922c365c37720149f90d90b1e9823eb82dad6830855b5f87537fa6fc0c"}, + {file = "duckdb-1.5.5-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e238060db5ca59879882a6e9b015e2c65d5c64ddf281ba1d7a9a2033764152cf"}, + {file = "duckdb-1.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:4acc72798ba1885a9c17d1242903d2cd502f13b1271c7677f7cab25d8578eceb"}, + {file = "duckdb-1.5.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b543841b0ae18a9c982345cfa3987e9c065d3a4b0f067daa473d92d1e65f528"}, + {file = "duckdb-1.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a925d06c2a4c3b64553d6cc1aced5028d376d4479bed689a7d47e9b1dccd80a"}, + {file = "duckdb-1.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0c42757cb34722144bd4dfb94b6f336339e7b2468f6813fa7fa9a319ba07bab4"}, + {file = "duckdb-1.5.5-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e72f9e1a4f90a5c8483ad4d540e495bf0834ba61c360b52499a573d7ed62a3f"}, + {file = "duckdb-1.5.5-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9b6f86ed85d4ef5e0211eaebf75d057bd8bb520bba438a95dd0f4e42234bbfe"}, + {file = "duckdb-1.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:9f4287f97ccf0c1f3d471e7115be2b067cbf99627e2d34bffd462dd64703cddc"}, + {file = "duckdb-1.5.5-cp311-cp311-win_arm64.whl", hash = "sha256:179633a3fc6296c75d57c69c1e239fa9e5cdcb670fd1dbff88a02663f932905c"}, + {file = "duckdb-1.5.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d4dd65f8941a604b947e0b9b4b4f7165988e29a23ec0b69b4038520956d9933e"}, + {file = "duckdb-1.5.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33db46679b071f108d57139493dee2d37e1f5efcf5c5c039c2969eed11a6c8a7"}, + {file = "duckdb-1.5.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f0b88535a5d86fdd63dba6ea02ab68c003dfb9e4892b11256ef24c4da208baae"}, + {file = "duckdb-1.5.5-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f316eae2323d9a851883fdf2dee91c1f9efe251ab33e14a2272f82a913422ed6"}, + {file = "duckdb-1.5.5-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a6d2d11859d82a936ebdcb30ce3d8a1cbb3e990bff05c12abb9b54c44fa7bd1"}, + {file = "duckdb-1.5.5-cp312-cp312-win_amd64.whl", hash = "sha256:ddfbdb096c11d51ee22492397d342c90a82e62c5d09961477895934d0a25372f"}, + {file = "duckdb-1.5.5-cp312-cp312-win_arm64.whl", hash = "sha256:2725d2b9ace3a4e75d72fc5a239f6a44b502c580edadb8fb2676db772c5f9282"}, + {file = "duckdb-1.5.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd98829b67788609017e65c761bd42a5dd0f9129441bed8bda4d6881ccf819f0"}, + {file = "duckdb-1.5.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:feead93c56679b79592d437c62975d39cb67adedffa7592c763baf8160ac7366"}, + {file = "duckdb-1.5.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:49c963d9469373d7aba8d750d9ea565ab823e94166efed953f184dd9b169b98c"}, + {file = "duckdb-1.5.5-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a736217825461732b5442d05a220f3da2e23a0dae114efbf08c9bf171b53098a"}, + {file = "duckdb-1.5.5-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:078e6a60dd8eedde5832f45422ca5c4a6b8c837aeabd8a56ca0b7d933f588053"}, + {file = "duckdb-1.5.5-cp313-cp313-win_amd64.whl", hash = "sha256:6826504277dba513c0c5d71d828456c94d729c9d2482f94b2e289f90a9167e28"}, + {file = "duckdb-1.5.5-cp313-cp313-win_arm64.whl", hash = "sha256:baa9c5702002fabb559ded2a39008f9f421fcbc7237d388b8213eff1e08858de"}, + {file = "duckdb-1.5.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8e6413dd40facb7b8ab21bd844450cd8f549b29e138635be9cf090ef4d2049e2"}, + {file = "duckdb-1.5.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:64078acfd16541132ac6e191eb81b2845554444a0305cc1aa581ba107e514aa8"}, + {file = "duckdb-1.5.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8c11775cc99a447618d5f1840126db17f2652f3eae05529df4f81f40e2df7151"}, + {file = "duckdb-1.5.5-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77bbc1e6ba12e1e06f9020117bdf848627ecfdf36f907550e62e008e6109dece"}, + {file = "duckdb-1.5.5-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fbf0f2d48b43c6c304d00463b463c27ead6c4b01c3c1816b750f728decf71afe"}, + {file = "duckdb-1.5.5-cp314-cp314-win_amd64.whl", hash = "sha256:9dc826c4b50e64f6c4e4d07a3a9cb075ef70ba3899dc43ec5493dc3d7b04b353"}, + {file = "duckdb-1.5.5-cp314-cp314-win_arm64.whl", hash = "sha256:63e48d4b74b15aeacd688976432a7225163df8c226eddeb8536bba2d4d4ff433"}, + {file = "duckdb-1.5.5.tar.gz", hash = "sha256:72f33ee57ca7595b23957671a2cc7f7fe2be0ecc2d68f63abedcfcaa3a5c1238"}, ] [package.extras] @@ -684,24 +663,41 @@ all = ["adbc-driver-manager", "fsspec", "ipython", "numpy", "pandas", "pyarrow"] [[package]] name = "duckdb-sqlalchemy" -version = "1.5.2.2" +version = "1.5.4.4" description = "DuckDB SQLAlchemy dialect for DuckDB and MotherDuck" optional = false python-versions = "<4,>=3.9" files = [ - {file = "duckdb_sqlalchemy-1.5.2.2-py3-none-any.whl", hash = "sha256:d13fa8262acf76ebf77becb468418535371a05afa80247009c3407fc6a50fb6a"}, - {file = "duckdb_sqlalchemy-1.5.2.2.tar.gz", hash = "sha256:a2699d1a5583659f013e48cd1b21c61fa60eec012023a95cdbef8e45d74abcea"}, + {file = "duckdb_sqlalchemy-1.5.4.4-py3-none-any.whl", hash = "sha256:68c76f9bc79b445b98bf3a965403476754f19e1249c4253463bbdfee52c862f3"}, + {file = "duckdb_sqlalchemy-1.5.4.4.tar.gz", hash = "sha256:809d0eb1b4c7dbe242f7e7ff169122257317756e668eacde4c3b1414065c4dca"}, ] [package.dependencies] duckdb = ">=0.5.0" packaging = ">=21" -sqlalchemy = ">=2.0.45" +sqlalchemy = {version = ">=2.0.0", markers = "python_version < \"3.14\""} [package.extras] -dev = ["fsspec (>=2025.2.0,<2027.0.0)", "github-action-utils (>=1.1.0,<2.0.0)", "hypothesis (>=6.75.2,<7.0.0)", "jupysql (>=0.11.1,<0.12.0)", "nox (>=2026.4.10,<2027.0.0)", "numpy (>=1.24,<2.0)", "numpy (>=1.26,<3.0)", "numpy (>=2.0,<3.0)", "pandas (>=1,<2.0)", "pandas (>=2.2,<4.0)", "pyarrow (>=22.0.0)", "pytest (>=8.0.0,<10.0.0)", "pytest-cov (>=7.1.0,<8.0.0)", "pytest-remotedata (>=0.4.0,<0.5.0)", "pytest-snapshot (>=0.9.0,<1.0.0)", "pytz (>=2024.2)", "toml (>=0.10.2,<0.11.0)", "ty (==0.0.34)"] +dev = ["fsspec (>=2025.2.0,<2027.0.0)", "github-action-utils (>=1.1.0,<2.0.0)", "hypothesis (>=6.75.2,<7.0.0)", "jupysql (>=0.11.1,<0.12.0)", "nox (>=2026.4.10,<2027.0.0)", "numpy (>=1.24,<2.0)", "numpy (>=1.26,<3.0)", "numpy (>=2.0,<3.0)", "pandas (>=1,<2.0)", "pandas (>=2.2,<4.0)", "pyarrow (>=22.0.0)", "pytest (>=8.0.0,<10.0.0)", "pytest-cov (>=7.1.0,<8.0.0)", "pytest-remotedata (>=0.4.0,<0.5.0)", "pytest-snapshot (>=0.9.0,<1.0.0)", "pytz (>=2024.2)", "toml (>=0.10.2,<0.11.0)", "ty (==0.0.60)"] devtools = ["nox (>=2026.4.10,<2027.0.0)", "pdbpp (>=0.11.0,<0.13.0)", "pre-commit (>=4.6.0,<4.7.0)"] +[[package]] +name = "exceptiongroup" +version = "1.3.1" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "fastparquet" version = "2024.11.0" @@ -764,24 +760,24 @@ lzo = ["python-lzo"] [[package]] name = "filelock" -version = "3.29.0" +version = "3.32.0" description = "A platform independent file lock." optional = false python-versions = ">=3.10" files = [ - {file = "filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258"}, - {file = "filelock-3.29.0.tar.gz", hash = "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90"}, + {file = "filelock-3.32.0-py3-none-any.whl", hash = "sha256:d396bea984af47333ef05e50eae7eff88c84256de6112aea0ec48a233c064fe3"}, + {file = "filelock-3.32.0.tar.gz", hash = "sha256:7be2ad23a14607ccc71808e68fe30848aeace7058ace17852f68e2a68e310402"}, ] [[package]] name = "fsspec" -version = "2026.4.0" +version = "2026.6.0" description = "File-system specification" optional = false python-versions = ">=3.10" files = [ - {file = "fsspec-2026.4.0-py3-none-any.whl", hash = "sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2"}, - {file = "fsspec-2026.4.0.tar.gz", hash = "sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4"}, + {file = "fsspec-2026.6.0-py3-none-any.whl", hash = "sha256:02e0b71817df9b2169dc30a16832045764def1191b43dcff5bb85bdee212d2a1"}, + {file = "fsspec-2026.6.0.tar.gz", hash = "sha256:f5bac145310fe30e16e1471bd6840b2d990d609e872251d7e674241822abf01a"}, ] [package.extras] @@ -809,7 +805,7 @@ smb = ["smbprotocol"] ssh = ["paramiko"] test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"] test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"] -test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "backports-zstd", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas (<3.0.0)", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] +test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "backports-zstd", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas (<3.0.0)", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr (<3.2.0)", "zstandard"] tqdm = ["tqdm"] [[package]] @@ -830,70 +826,90 @@ test = ["coverage", "pytest (>=7,<8.1)", "pytest-cov", "pytest-mock (>=3)"] [[package]] name = "greenlet" -version = "3.5.0" +version = "3.5.4" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.10" files = [ - {file = "greenlet-3.5.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:29ea813b2e1f45fa9649a17853b2b5465c4072fbcb072e5af6cd3a288216574a"}, - {file = "greenlet-3.5.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:804a70b328e706b785c6ef16187051c394a63dd1a906d89be24b6ad77759f13f"}, - {file = "greenlet-3.5.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:884f649de075b84739713d41dd4dfd41e2b910bfb769c4a3ea02ec1da52cd9bb"}, - {file = "greenlet-3.5.0-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4d0eadc7e4d9ffb2af4247b606cae307be8e448911e5a0d0b16d72fc3d224cfd"}, - {file = "greenlet-3.5.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b28037cb07768933c54d81bfe47a85f9f402f57d7d69743b991a713b63954eb"}, - {file = "greenlet-3.5.0-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:f8c30c2225f40dd76c50790f0eb3b5c7c18431efb299e2782083e1981feed243"}, - {file = "greenlet-3.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cda05425526240807408156b6960a17a79a0c760b813573b67027823be760977"}, - {file = "greenlet-3.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9c615f869163e14bb1ced20322d8038fb680b08236521ac3f30cd4c1288785a0"}, - {file = "greenlet-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:ba8f0bdc2fae6ce915dfd0c16d2d00bca7e4247c1eae4416e06430e522137858"}, - {file = "greenlet-3.5.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8f1cc966c126639cd152fdaa52624d2655f492faa79e013fea161de3e6dda082"}, - {file = "greenlet-3.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:362624e6a8e5bca3b8233e45eef33903a100e9539a2b995c364d595dbc4018b3"}, - {file = "greenlet-3.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5ecd83806b0f4c2f53b1018e0005cd82269ea01d42befc0368730028d850ed1c"}, - {file = "greenlet-3.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa94cb2288681e3a11645958f1871d48ee9211bd2f66628fdace505927d6e564"}, - {file = "greenlet-3.5.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ff251e9a0279522e62f6176412869395a64ddf2b5c5f782ff609a8216a4e662"}, - {file = "greenlet-3.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:64d6ac45f7271f48e45f67c95b54ef73534c52ec041fcda8edf520c6d811f4bc"}, - {file = "greenlet-3.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6d874e79afd41a96e11ff4c5d0bc90a80973e476fda1c2c64985667397df432b"}, - {file = "greenlet-3.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0ed006e4b86c59de7467eb2601cd1b77b5a7d657d1ee55e30fe30d76451edba4"}, - {file = "greenlet-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:703cb211b820dbffbbc55a16bfc6e4583a6e6e990f33a119d2cc8b83211119c8"}, - {file = "greenlet-3.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:6c18dfb59c70f5a94acd271c72e90128c3c776e41e5f07767908c8c1b74ad339"}, - {file = "greenlet-3.5.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:db2910d3c809444e0a20147361f343fe2798e106af8d9d8506f5305302655a9f"}, - {file = "greenlet-3.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ec9ea74e7268ace7f9aab1b1a4e730193fc661b39a993cd91c606c32d4a3628"}, - {file = "greenlet-3.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54d243512da35485fc7a6bf3c178fdda6327a9d6506fcdd62b1abd1e41b2927b"}, - {file = "greenlet-3.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:41353ec2ecedf7aa8f682753a41919f8718031a6edac46b8d3dc7ed9e1ceb136"}, - {file = "greenlet-3.5.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d280a7f5c331622c69f97eb167f33577ff2d1df282c41cd15907fc0a3ca198c"}, - {file = "greenlet-3.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:58c1c374fe2b3d852f9b6b11a7dff4c85404e51b9a596fd9e89cf904eb09866d"}, - {file = "greenlet-3.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1eb67d5adefb5bd2e182d42678a328979a209e4e82eb93575708185d31d1f588"}, - {file = "greenlet-3.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2628d6c86f6cb0cb45e0c3c54058bbec559f57eaae699447748cb3928150577e"}, - {file = "greenlet-3.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:d4d9f0624c775f2dfc56ba54d515a8c771044346852a918b405914f6b19d7fd8"}, - {file = "greenlet-3.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:83ed9f27f1680b50e89f40f6df348a290ea234b249a4003d366663a12eab94f2"}, - {file = "greenlet-3.5.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:5a5ed18de6a0f6cc7087f1563f6bd93fc7df1c19165ca01e9bde5a5dc281d106"}, - {file = "greenlet-3.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a717fbc46d8a354fa675f7c1e813485b6ba3885f9bef0cd56e5ba27d758ff5b"}, - {file = "greenlet-3.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ddc090c5c1792b10246a78e8c2163ebbe04cf877f9d785c230a7b27b39ad038e"}, - {file = "greenlet-3.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4964101b8585c144cbda5532b1aa644255126c08a265dae90c16e7a0e63aaa9d"}, - {file = "greenlet-3.5.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2094acd54b272cb6eae8c03dd87b3fa1820a4cef18d6889c378d503500a1dc13"}, - {file = "greenlet-3.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:7022615368890680e67b9965d33f5773aade330d5343bbe25560135aaa849eae"}, - {file = "greenlet-3.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5e05ba267789ea87b5a155cf0e810b1ab88bf18e9e8740813945ceb8ee4350ba"}, - {file = "greenlet-3.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0ecec963079cd58cbd14723582384f11f166fd58883c15dcbfb342e0bc9b5846"}, - {file = "greenlet-3.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:728d9667d8f2f586644b748dbd9bb67e50d6a9381767d1357714ea6825bb3bf5"}, - {file = "greenlet-3.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:47422135b1d308c14b2c6e758beedb1acd33bb91679f5670edf77bf46244722b"}, - {file = "greenlet-3.5.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:f35807464c4c58c55f0d31dfa83c541a5615d825c2fe3d2b95360cf7c4e3c0a8"}, - {file = "greenlet-3.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55fa7ea52771be44af0de27d8b80c02cd18c2c3cddde6c847ecebdf72418b6a1"}, - {file = "greenlet-3.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a97e4821aa710603f94de0da25f25096454d78ffdace5dc77f3a006bc01abba3"}, - {file = "greenlet-3.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bf2d8a80bec89ab46221ae45c5373d5ba0bd36c19aa8508e85c6cd7e5106cd37"}, - {file = "greenlet-3.5.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f52a464e4ed91780bdfbbdd2b97197f3accaa629b98c200f4dffada759f3ae7"}, - {file = "greenlet-3.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:1bae92a1dd94c5f9d9493c3a212dd874c202442047cf96446412c862feca83a2"}, - {file = "greenlet-3.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:762612baf1161ccb8437c0161c668a688223cba28e1bf038f4eb47b13e39ccdf"}, - {file = "greenlet-3.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:57a43c6079a89713522bc4bcb9f75070ecf5d3dbad7792bfe42239362cbf2a16"}, - {file = "greenlet-3.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:3bc59be3945ae9750b9e7d45067d01ae3fe90ea5f9ade99239dabdd6e28a5033"}, - {file = "greenlet-3.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:a96fcee45e03fe30a62669fd16ab5c9d3c172660d3085605cb1e2d1280d3c988"}, - {file = "greenlet-3.5.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:a10a732421ab4fec934783ce3e54763470d0181db6e3468f9103a275c3ed1853"}, - {file = "greenlet-3.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7fc391b1566f2907d17aaebe78f8855dc45675159a775fcf9e61f8ee0078e87f"}, - {file = "greenlet-3.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:680bd0e7ad5e8daa8a4aa89f68fd6adc834b8a8036dc256533f7e08f4a4b01f7"}, - {file = "greenlet-3.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1aa4ce8debcd4ea7fb2e150f3036588c41493d1d52c43538924ae1819003f4ce"}, - {file = "greenlet-3.5.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddb36c7d6c9c0a65f18c7258634e0c416c6ab59caac8c987b96f80c2ebda0112"}, - {file = "greenlet-3.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:728a73687e39ae9ca34e4694cbf2f049d3fbc7174639468d0f67200a97d8f9e2"}, - {file = "greenlet-3.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e5ddf316ced87539144621453c3aef229575825fe60c604e62bedc4003f372b2"}, - {file = "greenlet-3.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4a448128607be0de65342dc9b31be7f948ef4cc0bc8832069350abefd310a8f2"}, - {file = "greenlet-3.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d60097128cb0a1cab9ea541186ea13cd7b847b8449a7787c2e2350da0cb82d86"}, - {file = "greenlet-3.5.0.tar.gz", hash = "sha256:d419647372241bc68e957bf38d5c1f98852155e4146bd1e4121adea81f4f01e4"}, + {file = "greenlet-3.5.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:ac5bf81d79d2c8eeb2ef6359b2e1687a1e9ebf46c2b1f970da9a9255df51d190"}, + {file = "greenlet-3.5.4-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89f3738167bab8c1084b94e23023d41d247117ac149fa0fbcb5bd4cf6262b353"}, + {file = "greenlet-3.5.4-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e9a5e3406e3ed8125ae1a3b37c12f3434e2b1f0fa053197c5557895b4fb09606"}, + {file = "greenlet-3.5.4-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a2d614cb2372c7101a12ea8b96dd56f81c986d247c5a73db67063f3ed1ca4a52"}, + {file = "greenlet-3.5.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4ab9f0704bccf6d3b38e0d2130b7b33271cff11453690da074fa280c3aa8e8e7"}, + {file = "greenlet-3.5.4-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:188e4d142f243051d92a1f5c244a741da02dddc070a0620c842804d7b56d008c"}, + {file = "greenlet-3.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2cdaadc3d31445a8f782bde3cd37e49a2c2a9c6da6daf76a3e34c683b271a3c7"}, + {file = "greenlet-3.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:70bdfacdc183dac838b2a0aaff2dd6134a457c52fe68a9c6bbab435483d2b9df"}, + {file = "greenlet-3.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:69173331fbc5d64bfac0065d7e22c39cfcd089e9b18d125bdcd5079363b09616"}, + {file = "greenlet-3.5.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e883de250e299654b1f1680f72a1a9f9ba62c9bd1bce84099c90657349a8dfbb"}, + {file = "greenlet-3.5.4-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32802705c2c1ff25e8237b3bdacf2594fa02be80af8a66703eb7853ea7e68686"}, + {file = "greenlet-3.5.4-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:57aa201b351f7c7c75627c60d29e4d5b97a07d37efeb62b903466fca42c097d7"}, + {file = "greenlet-3.5.4-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9667862a2e38ad379f11b845daeda22c8989186def44f06962c9c4c05e556da7"}, + {file = "greenlet-3.5.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3fe76c2cac86b4f7a1e92865ac0a54384deb05c92986287c1a7110d9bd53071"}, + {file = "greenlet-3.5.4-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:ae53534b5dec0f4c2ec26f898f538dc8ea1ca3ef2927d597a9439e40a09da937"}, + {file = "greenlet-3.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1e1a4a684b16c45ba324e60b32a4386a87722bcb815d2a149d2182f9b401ca72"}, + {file = "greenlet-3.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e849e6e139b9671adeac505f72fc05f4af7fd1921faef40295e214fc3b361b59"}, + {file = "greenlet-3.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:dc418cf4c873357964d6624445ed09472e50def990c65dd4e76fc3ba8cd9cef6"}, + {file = "greenlet-3.5.4-cp311-cp311-win_arm64.whl", hash = "sha256:c38c902a0986eba1f6e7ba1ab39ad5195926abde90f3fe080e08212db62176da"}, + {file = "greenlet-3.5.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3d66250e8b09f182ede05490998c818b5961f7a3640332d44c4927caec7bbfe4"}, + {file = "greenlet-3.5.4-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c90e930c9c192e5b3ee9fb8bcd920ea3926155e2e3ded39fc697323addecee17"}, + {file = "greenlet-3.5.4-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:791fdfeeb9c6e0c7b10fa151bf110d2a6974866f13dcb5b1c7efae698245893a"}, + {file = "greenlet-3.5.4-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b7c895310363f310361e0fe2072af85269d2a2a285cd04c0c59e79a5e3670dcf"}, + {file = "greenlet-3.5.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f88193799d43dbf8c8a806d6405c9c52fe2af40bf75072a606357b33cc336c7f"}, + {file = "greenlet-3.5.4-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:13b980043cb1b3134e81ea469da1250ddcc6bfe6d245bbaa59168d9cdc8f228f"}, + {file = "greenlet-3.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b7a5f095767c4493afcd06067f2bb3b8716e3f3f9e92b99c88e7e99f885b3d4d"}, + {file = "greenlet-3.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:42afdc1ab5f66da8c586c32af9224a74a706b4f0ea0dc3a4188a0860a09c65c9"}, + {file = "greenlet-3.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:60149df8f462d1b230038e6590c23c3b4768bb5d6c022b3b6e82532b34b0b8a3"}, + {file = "greenlet-3.5.4-cp312-cp312-win_arm64.whl", hash = "sha256:77d6ce04fed0d9aeed42e0f37923cc43eba9b027bdd9c34546bb4ccd143d0fe0"}, + {file = "greenlet-3.5.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:24e61b88cb7e1b1d794b32a10cc346ac779681d6d74ff137a3e0a444d2bf1f02"}, + {file = "greenlet-3.5.4-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:870d730fec833f5a06906a32596cc099b9161594642a92a520b7a88911c95356"}, + {file = "greenlet-3.5.4-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ec5ff0d1878df6af3bf9b638a5a92a7d5693291de77c91bff10fa48519c604ef"}, + {file = "greenlet-3.5.4-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:07bd44616608d873d06735b63ef1a88191d6ca57c8d291d6559c71bc14c0893c"}, + {file = "greenlet-3.5.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d84d993f6e575c950d91a23c1345d18fe1a4310d447bf630849d7809196b52f0"}, + {file = "greenlet-3.5.4-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:3529a8a933582ad19e224792cac7372489526576b75b4c124e8e4f29948f4861"}, + {file = "greenlet-3.5.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:58023945f421093de5e6fa108c0985a8659d43f49e0216da25099369a121bcbd"}, + {file = "greenlet-3.5.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bae2728e1897aa8df8cb1af38cd48b3a743aefe29372de7b8b7a9f532501e69f"}, + {file = "greenlet-3.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:ca5726c0b08ca35ae873557266a78b2c3f3b2b7d7401aa5ff886c2045dd0111c"}, + {file = "greenlet-3.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:7c1303791d603080cac6fc3b34df51c3b75b723739c282c8029e48a0d241672f"}, + {file = "greenlet-3.5.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:7e8afa5eac028f8140ceafe5ceec66e6aa127ddcb21452d2a564dcd2900b5f22"}, + {file = "greenlet-3.5.4-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73b37afe369021423ea53dd3123e04bffa7e93ac64429b9f50835b2e4fcae7cf"}, + {file = "greenlet-3.5.4-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ef964f56dfcb6f9bbef2a190d9126795eac408716aeae47b5e7c73c32aafca9"}, + {file = "greenlet-3.5.4-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cef589bc65fae02d10bca2ac341191c5b33acc2967892ebf4fcbd10eabb7a74c"}, + {file = "greenlet-3.5.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c53ff01a5c53a40f2c16820ebc56d7c61a77f5fbe009dadd96292d5682f80f8"}, + {file = "greenlet-3.5.4-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:dfc41ae893d9ceaf22c824f2153a88b30651b20e8758c2cd9ac143f23640563c"}, + {file = "greenlet-3.5.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecca4d80d55a01ad6b23b33262662956149fbb7b2c6be2910f1705921958cbf3"}, + {file = "greenlet-3.5.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffbc533e0eaf8e80d8471411646ab88fe58f641d508c0b02b24494479f4d9ec"}, + {file = "greenlet-3.5.4-cp314-cp314-win_amd64.whl", hash = "sha256:305f69e6c4523d7f6979ed001cff4e5853c063e5da04880296603aa0227e544c"}, + {file = "greenlet-3.5.4-cp314-cp314-win_arm64.whl", hash = "sha256:f260930bbbbcf9caee661211235a5111c86dfe5832fdf6ae4570da1e0995320f"}, + {file = "greenlet-3.5.4-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:41ddab54e4b238f4a6c323f39b4e59e176affd5a94d461a9fb7583dac74240a3"}, + {file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3dabe3e2809013052c68bdf0b7fa5f5f2859c43a80803131ad61af9cabd7867"}, + {file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:27d3f00718634d4520a3a150154ac5da36f257869d41321953375b90bfbbc72c"}, + {file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:39169a11d87a6a263afda3e9a27d1df16d0f919d40a4837cc73986c9884c0dd8"}, + {file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbd60b5763c6543c1827e48faaf14ea9bfbad245f52b1a4d76a2a2d8884c6c66"}, + {file = "greenlet-3.5.4-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:bd3d1145f603b2db19feb9078c2e6855eb7c67e15580c010ed815cee519b86fd"}, + {file = "greenlet-3.5.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f00f910f0e7b35416c63b23ad78b769aeccfc1775f712b43c4ee525624a2eef7"}, + {file = "greenlet-3.5.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:91c26423753b92caf41ab3f98fd547d7374d4d9fc2d85be041886c1579d9255e"}, + {file = "greenlet-3.5.4-cp314-cp314t-win_amd64.whl", hash = "sha256:ee032b91fd8ec29ec6c4cea2b8c561b178435134bd0752c7334b94e9c736c132"}, + {file = "greenlet-3.5.4-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:178111881dd7a6c946471fda85485ec796e1043c2b939f694b096e2ecf986809"}, + {file = "greenlet-3.5.4-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d92df08dd65fede97fc37aad36c2e9dcda3b31c467f8e0c2c096456cb818e927"}, + {file = "greenlet-3.5.4-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:99e8f8c4ebc4fd80aa26c1280ae9ad43a0976e786349703a181cf0bae60413e5"}, + {file = "greenlet-3.5.4-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1f17e362d78e37559e0506c5a7d066bdd45073c36a0127a543e8a0df27242ff3"}, + {file = "greenlet-3.5.4-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:394de08dad5ffcb1f50c2159d93e398d9d2da3ed437645eaa54771fa720db9f0"}, + {file = "greenlet-3.5.4-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:cd320d998cbaa032932830448e39abf3c6a12901295e386e8114db926e10cffb"}, + {file = "greenlet-3.5.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:c883d61f2282d72c767a14936641b3efcbde9d82f1080712aaea0b1d3126cb88"}, + {file = "greenlet-3.5.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2a924f15d17957e252a810acefcb5942f5ca712298e8b6fcaed9a307d357522c"}, + {file = "greenlet-3.5.4-cp315-cp315-win_amd64.whl", hash = "sha256:ed17e5f3420360d5b459de8462efb52060399a5326a613d4cde31cef63ef95da"}, + {file = "greenlet-3.5.4-cp315-cp315-win_arm64.whl", hash = "sha256:f908898d6fa484ce4b6f447ce70ea99b52c503fee419e53cf74d60a16bc9e667"}, + {file = "greenlet-3.5.4-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:1833637f17d5e7472548a48575c394fe39f1b1890d676d162d86593610f44d8c"}, + {file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:12cda9122e03341f1cb6b8207a19d7a9d375e52f1b4e9243918375f40fd7b4b9"}, + {file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d83ae0e32d14957ab7170785a20f582635c8474deab1bfbb552b17e769a6ce25"}, + {file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:123aa379c962ed5fe90a880327e0c3066124ac64ec99e12a238be9fd8eb3db3d"}, + {file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f1467de1bb767f75db0aa34c195e3a496d8d1278c796e70c24ce205d3e99cde"}, + {file = "greenlet-3.5.4-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:adf2244d7f69409925a8f22ed22cc5f93cdfe5c9dc87ff3476be2c2aaae61a05"}, + {file = "greenlet-3.5.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:0fa53040b78b578120eecdc0265e3f1051487cc425d11a2b7c761daadf4feaa8"}, + {file = "greenlet-3.5.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:60e0bc961d367df506660e9ac0177a76bc6d81305300704b0977d1634f76efe2"}, + {file = "greenlet-3.5.4-cp315-cp315t-win_amd64.whl", hash = "sha256:f680e549edb3eaf21eea4e7fe101e15ec180c74b7879ab46adc080f22d4015d2"}, + {file = "greenlet-3.5.4-cp315-cp315t-win_arm64.whl", hash = "sha256:08fc36de8442d5c3e95b044550dbea9bf144d31ec0cc58e36fb241cb6ef6a994"}, + {file = "greenlet-3.5.4.tar.gz", hash = "sha256:0232ae1de90a8e07867bb127d7a6ba2301e859145489f25cda8a6096dabe1d20"}, ] [package.extras] @@ -916,13 +932,13 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.15" +version = "3.18" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8"}, - {file = "idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc"}, + {file = "idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2"}, + {file = "idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848"}, ] [package.extras] @@ -939,6 +955,17 @@ files = [ {file = "imagesize-2.0.0.tar.gz", hash = "sha256:8e8358c4a05c304f1fccf7ff96f036e7243a189e9e42e90851993c558cfe9ee3"}, ] +[[package]] +name = "iniconfig" +version = "2.3.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.10" +files = [ + {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"}, + {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"}, +] + [[package]] name = "isort" version = "5.13.2" @@ -1028,101 +1055,103 @@ referencing = ">=0.31.0" [[package]] name = "librt" -version = "0.11.0" +version = "0.13.0" description = "Mypyc runtime library" optional = false python-versions = ">=3.9" files = [ - {file = "librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f"}, - {file = "librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45"}, - {file = "librt-0.11.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c"}, - {file = "librt-0.11.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33"}, - {file = "librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884"}, - {file = "librt-0.11.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280"}, - {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c"}, - {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb"}, - {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783"}, - {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0"}, - {file = "librt-0.11.0-cp310-cp310-win32.whl", hash = "sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89"}, - {file = "librt-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4"}, - {file = "librt-0.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29"}, - {file = "librt-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9"}, - {file = "librt-0.11.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5"}, - {file = "librt-0.11.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b"}, - {file = "librt-0.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89"}, - {file = "librt-0.11.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc"}, - {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5"}, - {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7"}, - {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d"}, - {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412"}, - {file = "librt-0.11.0-cp311-cp311-win32.whl", hash = "sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d"}, - {file = "librt-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73"}, - {file = "librt-0.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c"}, - {file = "librt-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46"}, - {file = "librt-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3"}, - {file = "librt-0.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67"}, - {file = "librt-0.11.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a"}, - {file = "librt-0.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a"}, - {file = "librt-0.11.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f"}, - {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b"}, - {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766"}, - {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d"}, - {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8"}, - {file = "librt-0.11.0-cp312-cp312-win32.whl", hash = "sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a"}, - {file = "librt-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9"}, - {file = "librt-0.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c"}, - {file = "librt-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894"}, - {file = "librt-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c"}, - {file = "librt-0.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea"}, - {file = "librt-0.11.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230"}, - {file = "librt-0.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2"}, - {file = "librt-0.11.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3"}, - {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21"}, - {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930"}, - {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be"}, - {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e"}, - {file = "librt-0.11.0-cp313-cp313-win32.whl", hash = "sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e"}, - {file = "librt-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47"}, - {file = "librt-0.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44"}, - {file = "librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd"}, - {file = "librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4"}, - {file = "librt-0.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8"}, - {file = "librt-0.11.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b"}, - {file = "librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175"}, - {file = "librt-0.11.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03"}, - {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c"}, - {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3"}, - {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96"}, - {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe"}, - {file = "librt-0.11.0-cp314-cp314-win32.whl", hash = "sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f"}, - {file = "librt-0.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7"}, - {file = "librt-0.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1"}, - {file = "librt-0.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72"}, - {file = "librt-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa"}, - {file = "librt-0.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548"}, - {file = "librt-0.11.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2"}, - {file = "librt-0.11.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f"}, - {file = "librt-0.11.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51"}, - {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2"}, - {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085"}, - {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3"}, - {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd"}, - {file = "librt-0.11.0-cp314-cp314t-win32.whl", hash = "sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8"}, - {file = "librt-0.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c"}, - {file = "librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253"}, - {file = "librt-0.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f"}, - {file = "librt-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677"}, - {file = "librt-0.11.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab"}, - {file = "librt-0.11.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0"}, - {file = "librt-0.11.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1"}, - {file = "librt-0.11.0-cp39-cp39-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e"}, - {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa"}, - {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1"}, - {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5"}, - {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192"}, - {file = "librt-0.11.0-cp39-cp39-win32.whl", hash = "sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f"}, - {file = "librt-0.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3"}, - {file = "librt-0.11.0.tar.gz", hash = "sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1"}, + {file = "librt-0.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:34e47058fcc69a313293d6dee94216a4f30c929ae6f2476e58c5ba635aa639d5"}, + {file = "librt-0.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dbdd5b6509d0c2a8fe72cf494c299a61dbd58142a90a4190664ae159e4a7b547"}, + {file = "librt-0.13.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e56ea4ee4df77585a6b5c138f6538680886024fa559f5b55bd14b12e98e67b2"}, + {file = "librt-0.13.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f1f9cc4d09a46d9cb3c2063ae100629d3f52a6517c3c08c2f4c9828261883929"}, + {file = "librt-0.13.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f125f5d46b20f89dc5587a55cc416b4ba2a5b2ffda36d048ee120e17598a653a"}, + {file = "librt-0.13.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2608d3b39f9e0b4a66a130d9150c615cba40a5090d25eeeaa225e0e46de8c0ac"}, + {file = "librt-0.13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fd35e95ab5e45c3901d37110263c7db85a961110f5460588fe37f8c131f88a7"}, + {file = "librt-0.13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5f31b0aa13c9b04370d4da6be1ab7779776b3a075cceb6747a39a4be85fe1e40"}, + {file = "librt-0.13.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0b795f5fc70fbbb787ceaf79bb3a0d627bcc33c53de51741755263ec406b775a"}, + {file = "librt-0.13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36b306a623aaad96fe4b378692b54f9c0789fccd833b9851753d5fbf6138cfde"}, + {file = "librt-0.13.0-cp310-cp310-win32.whl", hash = "sha256:a3762e75fcac8c9e4dacaaf438bffd9003e2ca2c531b756f3c0035deefa674c8"}, + {file = "librt-0.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:d63bae12a8aeb51380be3438e4dc4bd27354d0f8e19166b2f44e3e94d6f552dc"}, + {file = "librt-0.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1b5a7bbff495baedbd9b916c367d66854008f8f3b575908ded477c499dc60082"}, + {file = "librt-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34bc7938b9fdf14fe32a406c19c71faf894c5cee7e7474bd0be2f17200b82d14"}, + {file = "librt-0.13.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f40e56b61b41be5f7dec938cfeffd660668cf4b5e72c78e7bd671d66b7bc2c79"}, + {file = "librt-0.13.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:9c5d02b89de5acd0379a51ec44a89476fb03df6145442e1c8ecd6bee2f91b176"}, + {file = "librt-0.13.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7db9a3ff32ef5f7d1703d93831a3316cdf0b537de6a1cc03cc8fdd09b9194e89"}, + {file = "librt-0.13.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3dbb2a31882456cadc7053378e81ad7ed7693db4ac9f98ab5f81ef034aa8ec9f"}, + {file = "librt-0.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c6014e3c80f9c1fe268ef8b0e0ef113bac672cc032f2f93866e7ddad4f3e663d"}, + {file = "librt-0.13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:091b60a4d2174fc1ec5c34cdc0b72efb6224753d76b7da61ebeab7a191aec8bd"}, + {file = "librt-0.13.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:66cb1138f384a191a6d75f986064841fcfdc0cea98f7bd9c9ab9b38049917588"}, + {file = "librt-0.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:17221a7569f8f292aa0014226e48aa25b8c2b08da18088cd230953d0ea0f9cd1"}, + {file = "librt-0.13.0-cp311-cp311-win32.whl", hash = "sha256:fc67741da44c6eaa90e01eafb586bbba9b51eb5b6ed381ee6f5ae72eb3316d21"}, + {file = "librt-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:cc99dfb62b23c9207c33d0be8a2e2af7a42e21e6ea388b380a0c948c7b88953b"}, + {file = "librt-0.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:40ccd13c252d3fe473ffc8a57be7565abc8b64cf1b108344c859d5164f7f3e0c"}, + {file = "librt-0.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30536798f4504c0fad0885b1d371b0539abb081e4570c9d7c641cb51141b49f0"}, + {file = "librt-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93d24ebb82aa4420b1409c389e7857bc35bd0b668007ac8172427d5c73cc8cc5"}, + {file = "librt-0.13.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb8a1adce42d8b75485a5d56a9623a50bcab995b6079f1dac59fc44034dd93d9"}, + {file = "librt-0.13.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0763ca2ab66058174f9dee426dc64f5e0a89c24a7df8d3fe3f1836c04e25de4b"}, + {file = "librt-0.13.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b222493da6e7b6199db9bd79502436cf5a27da3c1f7fa83c7e285444fc93fd03"}, + {file = "librt-0.13.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fadc63331f4388c3dc90090448f682a7e9feafc11481391c1e94f2f907a3976e"}, + {file = "librt-0.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:70d9c62a4cffd9f23396cd5ef93fc5d11b31596b9b7d6306074abe3d5fcf09bd"}, + {file = "librt-0.13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:66c0e7e6b02a155576df2c77ec933a70b72da726e248c494abf690923e624348"}, + {file = "librt-0.13.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ac04bcd3328eb91d99dfedf6a60d9c1f15d3434e6f6daf922f0420f7d90b85c7"}, + {file = "librt-0.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db327e7271e653c32040b85ae6188059c924b57d7e1e29f935523fa017cd4e82"}, + {file = "librt-0.13.0-cp312-cp312-win32.whl", hash = "sha256:860bd1d8ba48456ce08feaf8d343a8aaeb2fa086f2bcaa2a923fa3f7a3ff9aa3"}, + {file = "librt-0.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:e54a315caf843c8d77e388cadc56ea9ded569935ee2d2347d7ea94992e5aa6fa"}, + {file = "librt-0.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:c718e99a0992127af84385378460db624103b559ab260435abcfe77a4e4ed1c1"}, + {file = "librt-0.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a468951af16155824e88bdd8326ebe5bdb371f3ec0ac04642994b98201d914f3"}, + {file = "librt-0.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ae01d8512cc17079e53425635327dbf3f7ff57a42c00dec348bf79791c56444c"}, + {file = "librt-0.13.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32c26893cd085c1efe83219e78d866da23fb20a066101b8f68210004361d224c"}, + {file = "librt-0.13.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5929da1981a46bcf4b28b1b9499905f0ff58e2419da402a048234e9783acbc4b"}, + {file = "librt-0.13.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94b85d664d777bab6c0d709416cb42938251fda9e221b79e3a2215d85df5f4f9"}, + {file = "librt-0.13.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:531b2df3e9fe96b1fcf73a6d165921e4656be5f58d631d384ebce344298368db"}, + {file = "librt-0.13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:109b84a9edf69ad89dc1f66358659e14a031baca95e3e5b0060bd903ede8efd6"}, + {file = "librt-0.13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1304368a3e7ffc3e9db986796cc5326fdb5943a3567ecc137cff318e4240c0e7"}, + {file = "librt-0.13.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e4f9b472e7d308d94b62c801982065661158c6ed02790d6c7ddb4337cea0f9c1"}, + {file = "librt-0.13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9f836c37478f167a81200d8c8b2c920a22224564bed2c23d7aeec760965c367a"}, + {file = "librt-0.13.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:4000d961ff9598ac6ea603c6c836a5ed49bc205ade5fc378b998dfe1e2c36628"}, + {file = "librt-0.13.0-cp313-cp313-win32.whl", hash = "sha256:79e44cff71750d299d61a678e49995b0d5935a9cda238c2574daeca3ba536927"}, + {file = "librt-0.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:54dab44a847d5ad1acd05c8a83fe518ae685516ecf4d3f7cc6e3df2a66767650"}, + {file = "librt-0.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:d4cb6fbfdf874340ab5e51450753c0f817b6958a3621125ee695bbc3de866566"}, + {file = "librt-0.13.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:25218d94b1d2cbc0ba1d8a3f9dc9af578d9646e5ed16443a70cde1dfdcce6d71"}, + {file = "librt-0.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f26629539d4893c2957a16c41bb058e1e135c1f150f6a2e25ed047f64cf3f5c6"}, + {file = "librt-0.13.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a4517d47b2b8af26975a406fba7d314de9696d864252e0257c6ea90238cfe27f"}, + {file = "librt-0.13.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f19e181de5b3a1148bb3420b8c4b0b0ea0fce6950099724ad151d6cea5acc180"}, + {file = "librt-0.13.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22034924f5b42d5a56371cf271771bfeaabf235a7a8b6264bef2d20013f786c6"}, + {file = "librt-0.13.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7897db4e95e22468bdda33d8e012ceacd0182abf001e6389d763f0def6286b9"}, + {file = "librt-0.13.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ce61b3746545029d4f5c17d6bd74b676254ad98433086c846ffb5e8fa73f007"}, + {file = "librt-0.13.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:46c330e82565962c761dbce7941be2cff7db674ee807455a8d0cadc5f9b759b0"}, + {file = "librt-0.13.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:375f5af8f99cbaa99dd293af986e3d57caabc9ba81a5d3f021603764854197a1"}, + {file = "librt-0.13.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9320d34c3376ae204b2cd176e8d4883a013934e0aef822f1aed9c536490c275d"}, + {file = "librt-0.13.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:9af313c66157a69dc69ea0059a66961692250e0dc95af9c385a48ffb770a0d16"}, + {file = "librt-0.13.0-cp314-cp314-win32.whl", hash = "sha256:f2a7253458e34f33543551394ae4fe104b497ec2a65ac266074de64c1df82e37"}, + {file = "librt-0.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:a3dfe4edf10e8ed7e55b026a8bfc2c2a8704218b659cd4bffdf604fab966dc39"}, + {file = "librt-0.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:68a5faee4bba381cb93b5961f684a514cf0053cb92308ff9c792c2fea0b174c6"}, + {file = "librt-0.13.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a38fb81d8376dfa2f8963b265fec07637802b0d01e2a127c19c66cb070fb24f5"}, + {file = "librt-0.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d4c8d9bd5abce34b2e75edb3bf37ab0f34e49b1f915a40ae8468eb7c85bc5b46"}, + {file = "librt-0.13.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:387e2f1d27e89bffe0d3f520f0da0662c973fd607ca16c1808f8a5085419485e"}, + {file = "librt-0.13.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:4f6db193d2e5e0ed60359b9a5a682cd67205d0d3b1e459a867dd4b5c4e7eaa7a"}, + {file = "librt-0.13.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d38604854e8d22faadf683ec6c02bb0f886e2ba56ef981a1c36ee275f21ea22"}, + {file = "librt-0.13.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:371f7ce73026815dafd51c50ce38416e91428b28c4b2ec97cd39271164b0045c"}, + {file = "librt-0.13.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3aaedf52171bee90860704c560bc798fe83b76247df47568e0197e9b13c735a0"}, + {file = "librt-0.13.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:96bad8725a4f196a798366c25ce075d1f7543a4ec045ffc13e6a7ec095cdab04"}, + {file = "librt-0.13.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:6bf6a559ffe4a93bbea6cf31ddf01a7fd9ba342ef51f27beb178e318b74acd61"}, + {file = "librt-0.13.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:301067672387902c55f94b51d5022304b36c966ea9fe1f21caab99a9bef487c9"}, + {file = "librt-0.13.0-cp314-cp314t-win32.whl", hash = "sha256:5fdcf34f86de8fb66d7dc7589f96ba91c4aa46671200d400e6fd6f109a483f18"}, + {file = "librt-0.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:260c33e92263fa629b4f6d3c51967a1c2158fe6c33237aaa3ebeac586b085259"}, + {file = "librt-0.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2f281549a4c52ac7bb97997f14353f8bd0e53a34ca0dad1c905cfd0b4a58ae99"}, + {file = "librt-0.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f442e3954b1addc759faae22a7c9a3f1e16d7d1db3f484279dc27d62e06968fa"}, + {file = "librt-0.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9e786428f291dd2d2f1cbfc0e0caa45a2e395fab0ad3e2c9314daa8873414390"}, + {file = "librt-0.13.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21b7ac084f701a9cdff6139745a6620579d65a9379ac2d9d50a86368b109e63c"}, + {file = "librt-0.13.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a6e556d6aba31c93dd97ce661d66614d2429c0a3923f9dc8f0af7e8df10223a4"}, + {file = "librt-0.13.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3657346f867469e962549435aa05fd15330b1d6a92829f8e27988e194382d005"}, + {file = "librt-0.13.0-cp39-cp39-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:791aa18a373b90da8ac3c44fc77544f33fdf53ae403acdce9b39f1c26b4a3b94"}, + {file = "librt-0.13.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d6fb0eaa108814581c4d3bfbd068c3fb6757812a81415008d1bae08267cca360"}, + {file = "librt-0.13.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a001519c315d5db40710f2665d32c4791f1d4779fc96a9423fd18d92c8b9ac7b"}, + {file = "librt-0.13.0-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:d9188caac26e47671b52836a5e2a49873a7fc11c673b0c122d22515f98bc14e1"}, + {file = "librt-0.13.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:05d96b80b95d3a2721b619f8982b8558848b04875bb4772fd54842b59f61dd97"}, + {file = "librt-0.13.0-cp39-cp39-win32.whl", hash = "sha256:c3cd253cf32fe4f4662960d6bf7d55cb8be0c31a5d644a4d48aeafebaff3409a"}, + {file = "librt-0.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:b15e26cc0fe622d0c67e98bee6ef6bc8f792e20ee3006aa12627a00463d9399f"}, + {file = "librt-0.13.0.tar.gz", hash = "sha256:1d2a610c14ac0d0750ee0a3ab8548e83155258387891caaca04def4bf7289781"}, ] [[package]] @@ -1321,60 +1350,61 @@ pytest = ["pytest (>=7.2,<8.0)"] [[package]] name = "mypy" -version = "2.1.0" +version = "2.3.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.10" files = [ - {file = "mypy-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc"}, - {file = "mypy-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849"}, - {file = "mypy-2.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd"}, - {file = "mypy-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166"}, - {file = "mypy-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8"}, - {file = "mypy-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8"}, - {file = "mypy-2.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e"}, - {file = "mypy-2.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41"}, - {file = "mypy-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca"}, - {file = "mypy-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538"}, - {file = "mypy-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398"}, - {file = "mypy-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563"}, - {file = "mypy-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389"}, - {file = "mypy-2.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666"}, - {file = "mypy-2.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af"}, - {file = "mypy-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6"}, - {file = "mypy-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211"}, - {file = "mypy-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b"}, - {file = "mypy-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22"}, - {file = "mypy-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b"}, - {file = "mypy-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8"}, - {file = "mypy-2.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5"}, - {file = "mypy-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e"}, - {file = "mypy-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e"}, - {file = "mypy-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285"}, - {file = "mypy-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5"}, - {file = "mypy-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65"}, - {file = "mypy-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d"}, - {file = "mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2"}, - {file = "mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f"}, - {file = "mypy-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4"}, - {file = "mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef"}, - {file = "mypy-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135"}, - {file = "mypy-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21"}, - {file = "mypy-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57"}, - {file = "mypy-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e"}, - {file = "mypy-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780"}, - {file = "mypy-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd"}, - {file = "mypy-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08"}, - {file = "mypy-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081"}, - {file = "mypy-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7"}, - {file = "mypy-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6"}, - {file = "mypy-2.1.0-py3-none-any.whl", hash = "sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289"}, - {file = "mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633"}, + {file = "mypy-2.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1fa8d916ac3b705af733c4c1e6c9ebe38fd0d52beb15b105c3e8355b55e6ecdc"}, + {file = "mypy-2.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:28e1e2af8cd8fff551fd30f2fe4b03fb76764ac8b1ba6c6a1bd00ad32b412db3"}, + {file = "mypy-2.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3e77244df3843048c3f927182916730e40c124cbaa43905c1fb86cb382aa0805"}, + {file = "mypy-2.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9559ab18a9c9957dfa3004ab57cd4bac5f26a724329a9584e583367f0c2e1117"}, + {file = "mypy-2.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:09abd66d8685e73f8f7d17b847c3e104d9a7b164a8706ea87d6c96a3d45816d5"}, + {file = "mypy-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e91adad1ca81742ac7ef9893959911df867752206b37135185e88dfb3c89494"}, + {file = "mypy-2.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:6f99ec626e3c3a2f7c0b22c5b90ddb5dabb1c18729c971e9bdaca1f1766d2cee"}, + {file = "mypy-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3419d00717afbc5265b50dd14b1278f29ea4884dd398ab67873489ac093fd329"}, + {file = "mypy-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cfca8ee88544090f86b6dcce05ec55d66eb48a762412ac2507810ba4bd793b6f"}, + {file = "mypy-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:75cbb4b9ef04a0c84a957f07abc4504fbf64b8dcc145675101f2d3a78a4b1d6a"}, + {file = "mypy-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:982e3d53dd23d0a4cef67dd66791fdbede0cf38f9eb617bf47663554c51e1e36"}, + {file = "mypy-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85c5385b93012ffa3b31479ab579aef5415f4f3a32c6cf1ae07a984d2a0ff461"}, + {file = "mypy-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:13b1b16e2fa39f3b2e33fb1c468abc7a69369fa2e886b4b87b5afc81472325cd"}, + {file = "mypy-2.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:b5cd2f027a972a4a5f2278a11fac9747f5f81a53a30b714d74950b6807e55568"}, + {file = "mypy-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d53fc67b9d28a43c6199077f49fea0f05839e36cf6158500331c9549225e5a5"}, + {file = "mypy-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fbc00cee7bdbb9291979ddc9d08034a29dfcda4932628c9bbc28c1edd589df0c"}, + {file = "mypy-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:04e617030eca5221909c8b7d8d7fd1c637948199aa2100b2ad9813feb07e1491"}, + {file = "mypy-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56c184d2c20ca6b6378d58d1960270a767f41f5e44acbbd27f05effef4f4e1d7"}, + {file = "mypy-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3961a4a34b05f7c74b0f05aa51fbfe99a2d1e126038df40318d15c8f558b7ef3"}, + {file = "mypy-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1942b9314d4c784b8ea1dbab4972603290e5dd5630f06675f13aec97526bc4c"}, + {file = "mypy-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:be51653d7669d7d7955d613b8d0bb57d5b652eaf71a873ddf65ac87254dd2595"}, + {file = "mypy-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:91ad22a52ae2c7e621c2f67c94d5a17f66b3209a4cff5cf8a573579835c69e97"}, + {file = "mypy-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:99ac767cc5d3b64c8d0ae226ead10c96694f94e4e7da1668642225dcd4e75aac"}, + {file = "mypy-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6d2c484742a4d7b0ed6d07b143375624d3b899c5749c7b3c947f56261f48a6"}, + {file = "mypy-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7da939dd335cfd2ad788bdfd081c9f4e47634ab995e5a45eb15fd1e5bc052f8b"}, + {file = "mypy-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7247eb2824f996722a949530183394921ca71deb9680052a338cf53cff7925c2"}, + {file = "mypy-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:75b0984bb3cbd76bb5c9291a8671f7ae66ca3b51c7584c358fc2e923259f0757"}, + {file = "mypy-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:d78fcf900b59cb7e82cb7e3a235e31b462d9333d92285bd1e4952d355b8ffba1"}, + {file = "mypy-2.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ea317b060ce83e26050f8f9e4d7d6bf44ed7597c8ff9990bccffbb9d1d8522db"}, + {file = "mypy-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:094af99f92638aa92852326188b85a89e50f4a472f44827c03362228482f0762"}, + {file = "mypy-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de121747278144fc9ae7caa2e978cf5df12aebc82933182f5b3b86081a30baef"}, + {file = "mypy-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37fa4de896a84e2dc9200d91e614c22563b43d1a266789d4bbac7b22ebe6192b"}, + {file = "mypy-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f1b3a98dfd21058bc759bb3337d5d1f61d0fdf9f3cf9c00f4291790fb5427bff"}, + {file = "mypy-2.3.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:944c665d984157cb96a679dfb7a4a81dd1d36b24b9c284b699514e6e626b82d4"}, + {file = "mypy-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:4359424140d985192c778c1ce2c114a10c1ca58a381ed79cfa70d37df94b299f"}, + {file = "mypy-2.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:3dd0bed92c4bdec57c42505b96416fb9e6a5aa7be84d2809bcd5f2ecec2860d7"}, + {file = "mypy-2.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:691fdc37132b1ae628d834f672e74de83462d9fb4aff621835767fb43a8dd373"}, + {file = "mypy-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:aec15d465d477558fd842757b487849007311cf3897849cdda0e3162ac0ac556"}, + {file = "mypy-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b352b7e49f5e6576009e8df730e1ff4f915cb565b851b396d2ffe2f5a6f5da88"}, + {file = "mypy-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c6c6bf687b17f90dbfcad95b960d32eaa0154c00da45f03ab50bf8952e047fe"}, + {file = "mypy-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f4ed18f111bfe2d599bca7468e7f9251042c1c2118f762c8de2766a56d773c60"}, + {file = "mypy-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0b025a93cffb9781d231f232be07a17912f35f10a313c24f301c81e842870654"}, + {file = "mypy-2.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:adebc76aab4f3495a88b41d48aa4aff0c03f2822501da76625afcca5975f19e5"}, + {file = "mypy-2.3.0-py3-none-any.whl", hash = "sha256:6b1cdb579446b60432432b2b2403a6201b4b475a004d7f488511c9ba177c9e88"}, + {file = "mypy-2.3.0.tar.gz", hash = "sha256:465965d41cd9a2726694e983e8ce7113259327bec798115d1e1dfa2a52fb666e"}, ] [package.dependencies] -ast-serialize = ">=0.3.0,<1.0.0" -librt = {version = ">=0.11.0", markers = "platform_python_implementation != \"PyPy\""} +ast-serialize = ">=0.6.0,<1.0.0" +librt = {version = ">=0.13.0", markers = "platform_python_implementation != \"PyPy\""} mypy_extensions = ">=1.0.0" pathspec = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -1653,15 +1683,30 @@ scramp = ">=1.4.5" [[package]] name = "platformdirs" -version = "4.9.6" +version = "4.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.10" files = [ - {file = "platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917"}, - {file = "platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a"}, + {file = "platformdirs-4.11.0-py3-none-any.whl", hash = "sha256:360ccded2b7fce0af0ff80cc8f5942a1c5d99b0e856033acb030bfc634709e74"}, + {file = "platformdirs-4.11.0.tar.gz", hash = "sha256:0555d18370482847566ffabcaa53ad7c6c1c29f195989ae1ed634a05f76ea1e0"}, ] +[[package]] +name = "pluggy" +version = "1.6.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["coverage", "pytest", "pytest-benchmark"] + [[package]] name = "pockets" version = "0.9.1" @@ -1696,20 +1741,20 @@ virtualenv = ">=20.10.0" [[package]] name = "prettytable" -version = "3.17.0" +version = "3.18.0" description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" optional = false python-versions = ">=3.10" files = [ - {file = "prettytable-3.17.0-py3-none-any.whl", hash = "sha256:aad69b294ddbe3e1f95ef8886a060ed1666a0b83018bbf56295f6f226c43d287"}, - {file = "prettytable-3.17.0.tar.gz", hash = "sha256:59f2590776527f3c9e8cf9fe7b66dd215837cca96a9c39567414cbc632e8ddb0"}, + {file = "prettytable-3.18.0-py3-none-any.whl", hash = "sha256:b3346e0e6f79180833aebaac088ae926340586cf6d7d991b9eb125b65f72313a"}, + {file = "prettytable-3.18.0.tar.gz", hash = "sha256:439217116152244369caf3d9f1caf2f9fe29b03bd79e88d2928c8e718c95d680"}, ] [package.dependencies] -wcwidth = "*" +wcwidth = ">=0.3.5" [package.extras] -tests = ["pytest", "pytest-cov", "pytest-lazy-fixtures"] +tests = ["pytest (>=9)", "pytest-cov", "pytest-lazy-fixtures"] [[package]] name = "psycopg2-binary" @@ -1916,6 +1961,102 @@ files = [ ed25519 = ["PyNaCl (>=1.6.2)"] rsa = ["cryptography (>=46.0.7)"] +[[package]] +name = "pyodbc" +version = "5.3.0" +description = "DB API module for ODBC" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pyodbc-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6682cdec78f1302d0c559422c8e00991668e039ed63dece8bf99ef62173376a5"}, + {file = "pyodbc-5.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9cd3f0a9796b3e1170a9fa168c7e7ca81879142f30e20f46663b882db139b7d2"}, + {file = "pyodbc-5.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46185a1a7f409761716c71de7b95e7bbb004390c650d00b0b170193e3d6224bb"}, + {file = "pyodbc-5.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:349a9abae62a968b98f6bbd23d2825151f8d9de50b3a8f5f3271b48958fdb672"}, + {file = "pyodbc-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ac23feb7ddaa729f6b840639e92f83ff0ccaa7072801d944f1332cd5f5b05f47"}, + {file = "pyodbc-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8aa396c6d6af52ccd51b8c8a5bffbb46fd44e52ce07ea4272c1d28e5e5b12722"}, + {file = "pyodbc-5.3.0-cp310-cp310-win32.whl", hash = "sha256:46869b9a6555ff003ed1d8ebad6708423adf2a5c88e1a578b9f029fb1435186e"}, + {file = "pyodbc-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:705903acf6f43c44fc64e764578d9a88649eb21bf7418d78677a9d2e337f56f2"}, + {file = "pyodbc-5.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:c68d9c225a97aedafb7fff1c0e1bfe293093f77da19eaf200d0e988fa2718d16"}, + {file = "pyodbc-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ebc3be93f61ea0553db88589e683ace12bf975baa954af4834ab89f5ee7bf8ae"}, + {file = "pyodbc-5.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9b987a25a384f31e373903005554230f5a6d59af78bce62954386736a902a4b3"}, + {file = "pyodbc-5.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:676031723aac7dcbbd2813bddda0e8abf171b20ec218ab8dfb21d64a193430ea"}, + {file = "pyodbc-5.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5c30c5cd40b751f77bbc73edd32c4498630939bcd4e72ee7e6c9a4b982cc5ca"}, + {file = "pyodbc-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2035c7dfb71677cd5be64d3a3eb0779560279f0a8dc6e33673499498caa88937"}, + {file = "pyodbc-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5cbe4d753723c8a8f65020b7a259183ef5f14307587165ce37e8c7e251951852"}, + {file = "pyodbc-5.3.0-cp311-cp311-win32.whl", hash = "sha256:d255f6b117d05cfc046a5201fdf39535264045352ea536c35777cf66d321fbb8"}, + {file = "pyodbc-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:f1ad0e93612a6201621853fc661209d82ff2a35892b7d590106fe8f97d9f1f2a"}, + {file = "pyodbc-5.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:0df7ff47fab91ea05548095b00e5eb87ed88ddf4648c58c67b4db95ea4913e23"}, + {file = "pyodbc-5.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5ebf6b5d989395efe722b02b010cb9815698a4d681921bf5db1c0e1195ac1bde"}, + {file = "pyodbc-5.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:197bb6ddafe356a916b8ee1b8752009057fce58e216e887e2174b24c7ab99269"}, + {file = "pyodbc-5.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c6ccb5315ec9e081f5cbd66f36acbc820ad172b8fa3736cf7f993cdf69bd8a96"}, + {file = "pyodbc-5.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5dd3d5e469f89a3112cf8b0658c43108a4712fad65e576071e4dd44d2bd763c7"}, + {file = "pyodbc-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b180bc5e49b74fd40a24ef5b0fe143d0c234ac1506febe810d7434bf47cb925b"}, + {file = "pyodbc-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e3c39de3005fff3ae79246f952720d44affc6756b4b85398da4c5ea76bf8f506"}, + {file = "pyodbc-5.3.0-cp312-cp312-win32.whl", hash = "sha256:d32c3259762bef440707098010035bbc83d1c73d81a434018ab8c688158bd3bb"}, + {file = "pyodbc-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe77eb9dcca5fc1300c9121f81040cc9011d28cff383e2c35416e9ec06d4bc95"}, + {file = "pyodbc-5.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:afe7c4ac555a8d10a36234788fc6cfc22a86ce37fc5ba88a1f75b3e6696665dc"}, + {file = "pyodbc-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e9ab0b91de28a5ab838ac4db0253d7cc8ce2452efe4ad92ee6a57b922bf0c24"}, + {file = "pyodbc-5.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6132554ffbd7910524d643f13ce17f4a72f3a6824b0adef4e9a7f66efac96350"}, + {file = "pyodbc-5.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1629af4706e9228d79dabb4863c11cceb22a6dab90700db0ef449074f0150c0d"}, + {file = "pyodbc-5.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ceaed87ba2ea848c11223f66f629ef121f6ebe621f605cde9cfdee4fd9f4b68"}, + {file = "pyodbc-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3cc472c8ae2feea5b4512e23b56e2b093d64f7cbc4b970af51da488429ff7818"}, + {file = "pyodbc-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c79df54bbc25bce9f2d87094e7b39089c28428df5443d1902b0cc5f43fd2da6f"}, + {file = "pyodbc-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c2eb0b08e24fe5c40c7ebe9240c5d3bd2f18cd5617229acee4b0a0484dc226f2"}, + {file = "pyodbc-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:01166162149adf2b8a6dc21a212718f205cabbbdff4047dc0c415af3fd85867e"}, + {file = "pyodbc-5.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:363311bd40320b4a61454bebf7c38b243cd67c762ed0f8a5219de3ec90c96353"}, + {file = "pyodbc-5.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3f1bdb3ce6480a17afaaef4b5242b356d4997a872f39e96f015cabef00613797"}, + {file = "pyodbc-5.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7713c740a10f33df3cb08f49a023b7e1e25de0c7c99650876bbe717bc95ee780"}, + {file = "pyodbc-5.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cf18797a12e70474e1b7f5027deeeccea816372497e3ff2d46b15bec2d18a0cc"}, + {file = "pyodbc-5.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:08b2439500e212625471d32f8fde418075a5ddec556e095e5a4ba56d61df2dc6"}, + {file = "pyodbc-5.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:729c535341bb09c476f219d6f7ab194bcb683c4a0a368010f1cb821a35136f05"}, + {file = "pyodbc-5.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c67e7f2ce649155ea89beb54d3b42d83770488f025cf3b6f39ca82e9c598a02e"}, + {file = "pyodbc-5.3.0-cp314-cp314-win32.whl", hash = "sha256:a48d731432abaee5256ed6a19a3e1528b8881f9cb25cb9cf72d8318146ea991b"}, + {file = "pyodbc-5.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:58635a1cc859d5af3f878c85910e5d7228fe5c406d4571bffcdd281375a54b39"}, + {file = "pyodbc-5.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:754d052030d00c3ac38da09ceb9f3e240e8dd1c11da8906f482d5419c65b9ef5"}, + {file = "pyodbc-5.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f927b440c38ade1668f0da64047ffd20ec34e32d817f9a60d07553301324b364"}, + {file = "pyodbc-5.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:25c4cfb2c08e77bc6e82f666d7acd52f0e52a0401b1876e60f03c73c3b8aedc0"}, + {file = "pyodbc-5.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bc834567c2990584b9726cba365834d039380c9dbbcef3030ddeb00c6541b943"}, + {file = "pyodbc-5.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8339d3094858893c1a68ee1af93efc4dff18b8b65de54d99104b99af6306320d"}, + {file = "pyodbc-5.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74528fe148980d0c735c0ebb4a4dc74643ac4574337c43c1006ac4d09593f92d"}, + {file = "pyodbc-5.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d89a7f2e24227150c13be8164774b7e1f9678321a4248f1356a465b9cc17d31e"}, + {file = "pyodbc-5.3.0-cp314-cp314t-win32.whl", hash = "sha256:af4d8c9842fc4a6360c31c35508d6594d5a3b39922f61b282c2b4c9d9da99514"}, + {file = "pyodbc-5.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bfeb3e34795d53b7d37e66dd54891d4f9c13a3889a8f5fe9640e56a82d770955"}, + {file = "pyodbc-5.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:13656184faa3f2d5c6f19b701b8f247342ed581484f58bf39af7315c054e69db"}, + {file = "pyodbc-5.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0263323fc47082c2bf02562f44149446bbbfe91450d271e44bffec0c3143bfb1"}, + {file = "pyodbc-5.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:452e7911a35ee12a56b111ac5b596d6ed865b83fcde8427127913df53132759e"}, + {file = "pyodbc-5.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b35b9983ad300e5aea82b8d1661fc9d3afe5868de527ee6bd252dd550e61ecd6"}, + {file = "pyodbc-5.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e981db84fee4cebec67f41bd266e1e7926665f1b99c3f8f4ea73cd7f7666e381"}, + {file = "pyodbc-5.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:25b6766e56748eb1fc1d567d863e06cbb7b7c749a41dfed85db0031e696fa39a"}, + {file = "pyodbc-5.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2eb7151ed0a1959cae65b6ac0454f5c8bbcd2d8bafeae66483c09d58b0c7a7fc"}, + {file = "pyodbc-5.3.0-cp39-cp39-win32.whl", hash = "sha256:fc5ac4f2165f7088e74ecec5413b5c304247949f9702c8853b0e43023b4187e8"}, + {file = "pyodbc-5.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:c25dc9c41f61573bdcf61a3408c34b65e4c0f821b8f861ca7531b1353b389804"}, + {file = "pyodbc-5.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:101313a21d2654df856a60e4a13763e4d9f6c5d3fd974bcf3fc6b4e86d1bbe8e"}, + {file = "pyodbc-5.3.0.tar.gz", hash = "sha256:2fe0e063d8fb66efd0ac6dc39236c4de1a45f17c33eaded0d553d21c199f4d05"}, +] + +[[package]] +name = "pytest" +version = "9.1.1" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.10" +files = [ + {file = "pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c"}, + {file = "pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313"}, +] + +[package.dependencies] +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} +iniconfig = ">=1.0.1" +packaging = ">=22" +pluggy = ">=1.5,<2" +pygments = ">=2.7.2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1932,23 +2073,19 @@ six = ">=1.5" [[package]] name = "python-discovery" -version = "1.3.1" +version = "1.5.0" description = "Python interpreter discovery" optional = false python-versions = ">=3.8" files = [ - {file = "python_discovery-1.3.1-py3-none-any.whl", hash = "sha256:ed188687ebb3b82c01a17cd5ac62fc94d9f6487a7f1a0f9dfe89753fec91039c"}, - {file = "python_discovery-1.3.1.tar.gz", hash = "sha256:62f6db28064c9613e7ca76cb3f00c38c839a07c31c00dfe7ed0986493d2150a6"}, + {file = "python_discovery-1.5.0-py3-none-any.whl", hash = "sha256:70c4fc61b4e7404e44f01d6fc44a715c4d685ca6cea83d295922f05891877c98"}, + {file = "python_discovery-1.5.0.tar.gz", hash = "sha256:3e014c6327154d3dda27939a9a0dc9c5c000439f1906d3f303b48f984bd2ecef"}, ] [package.dependencies] filelock = ">=3.15.4" platformdirs = ">=4.3.6,<5" -[package.extras] -docs = ["furo (>=2025.12.19)", "sphinx (>=9.1)", "sphinx-autodoc-typehints (>=3.6.3)", "sphinxcontrib-mermaid (>=2)", "sphinxcontrib-towncrier (>=0.4)", "towncrier (>=25.8)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.5.4)", "pytest (>=8.3.5)", "pytest-mock (>=3.14)", "setuptools (>=75.1)"] - [[package]] name = "python-dotenv" version = "1.2.2" @@ -2273,13 +2410,13 @@ toml = ["tomli (>=2.0,<3.0)"] [[package]] name = "scramp" -version = "1.4.8" +version = "1.4.12" description = "An implementation of the SCRAM protocol." optional = false python-versions = ">=3.10" files = [ - {file = "scramp-1.4.8-py3-none-any.whl", hash = "sha256:87c2f15976845a2872fe5490a06097f0d01813cceb53774ea168c911f2ad025c"}, - {file = "scramp-1.4.8.tar.gz", hash = "sha256:bd018fabfe46343cceeb9f1c3e8d23f55770271e777e3accbfaee3ff0a316e71"}, + {file = "scramp-1.4.12-py3-none-any.whl", hash = "sha256:6adb2828c5d64bd7785a6878eed30f66ce0fae60bf5fc07c26ce1f521db3ec3e"}, + {file = "scramp-1.4.12.tar.gz", hash = "sha256:94b38decf26005b835050d06541a5aefb9914497f4de789c6d82a0abc4b934de"}, ] [package.dependencies] @@ -2328,13 +2465,13 @@ sqlalchemy = ">=2.0.0,<3.0.0" [[package]] name = "snowballstemmer" -version = "3.0.1" -description = "This package provides 32 stemmers for 30 languages generated from Snowball algorithms." +version = "3.1.1" +description = "This package provides 36 stemmers for 34 languages generated from Snowball algorithms." optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*" +python-versions = ">=3.3" files = [ - {file = "snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064"}, - {file = "snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"}, + {file = "snowballstemmer-3.1.1-py3-none-any.whl", hash = "sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752"}, + {file = "snowballstemmer-3.1.1.tar.gz", hash = "sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260"}, ] [[package]] @@ -2468,13 +2605,13 @@ test = ["flake8", "mypy", "pytest"] [[package]] name = "sphinxcontrib-mermaid" -version = "2.0.2" +version = "2.0.3" description = "Mermaid diagrams in your Sphinx-powered docs" optional = false python-versions = ">=3.10" files = [ - {file = "sphinxcontrib_mermaid-2.0.2-py3-none-any.whl", hash = "sha256:d862e514991279fb4816302c5cfe167d2557bf3ce7125ae0cb47dac80a0f46ce"}, - {file = "sphinxcontrib_mermaid-2.0.2.tar.gz", hash = "sha256:f09576c78ca93fa0e3034fd9c45aaffa7c44ab449de9c43b8b8d262afe52bc66"}, + {file = "sphinxcontrib_mermaid-2.0.3-py3-none-any.whl", hash = "sha256:f001ed36a55c108f6221a2d656a441c487ee30651b54db72b7c752a20c7a66e8"}, + {file = "sphinxcontrib_mermaid-2.0.3.tar.gz", hash = "sha256:a6865ef6b65b225c5403a3170de63a04a07227cada11a4a71a6b87b4f9ed185a"}, ] [package.dependencies] @@ -2751,35 +2888,34 @@ files = [ [[package]] name = "tomlkit" -version = "0.15.0" +version = "0.15.1" description = "Style preserving TOML library" optional = false python-versions = ">=3.9" files = [ - {file = "tomlkit-0.15.0-py3-none-any.whl", hash = "sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738"}, - {file = "tomlkit-0.15.0.tar.gz", hash = "sha256:7d1a9ecba3086638211b13814ea79c90dd54dd11993564376f3aa92271f5c7a3"}, + {file = "tomlkit-0.15.1-py3-none-any.whl", hash = "sha256:177a05aece5a8ca5266fd3c448abb47b8d352f09d477d3ca8332db4d89b24304"}, + {file = "tomlkit-0.15.1.tar.gz", hash = "sha256:e25bbf38843005246210a12982776f27f99cb9be67160e14434d0c0d21ee1e97"}, ] [[package]] name = "tqdm" -version = "4.67.3" +version = "4.69.0" description = "Fast, Extensible Progress Meter" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf"}, - {file = "tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb"}, + {file = "tqdm-4.69.0-py3-none-any.whl", hash = "sha256:9979978912be667a6ef21fd5d8abf54e324e63d82f7f43c360792ebc2bc4e622"}, + {file = "tqdm-4.69.0.tar.gz", hash = "sha256:700c5e85dcd5f009dd6222588a29180a193a748247a5d855b4d67db93d79a53b"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] -discord = ["requests"] +discord = ["envwrap", "requests"] notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] +slack = ["envwrap", "slack-sdk"] +telegram = ["envwrap", "requests"] [[package]] name = "ty" @@ -2849,13 +2985,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.15.0" +version = "4.16.0" description = "Backported and Experimental Type Hints for Python 3.9+" optional = false python-versions = ">=3.9" files = [ - {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, - {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, + {file = "typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8"}, + {file = "typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5"}, ] [[package]] @@ -2875,13 +3011,13 @@ typing-extensions = ">=3.7.4" [[package]] name = "tzdata" -version = "2026.2" +version = "2026.3" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7"}, - {file = "tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10"}, + {file = "tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931"}, + {file = "tzdata-2026.3.tar.gz", hash = "sha256:4a1518b8993086a7982523e071643f3c0e5f213e75b21318e78bcabfff9d1415"}, ] [[package]] @@ -2903,130 +3039,130 @@ zstd = ["backports-zstd (>=1.0.0)"] [[package]] name = "virtualenv" -version = "21.3.3" +version = "21.7.0" description = "Virtual Python Environment builder" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "virtualenv-21.3.3-py3-none-any.whl", hash = "sha256:7d5987d8369e098e41406efb780a3d4ca79280097293899e351a6407ee153ab3"}, - {file = "virtualenv-21.3.3.tar.gz", hash = "sha256:f5bda277e553b1c2b3c1a8debfc30496e1288cc93ce6b7b71b3280047e317328"}, + {file = "virtualenv-21.7.0-py3-none-any.whl", hash = "sha256:a8370c1c5530fbabf955e40b8fbbc68a431648b10f9433faa587db30a06e51dd"}, + {file = "virtualenv-21.7.0.tar.gz", hash = "sha256:7f9519b9432ff11b6e1a3e94061664efc2ff99ea21780e3cf4f6bd0a5da8b37c"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = {version = ">=3.24.2,<4", markers = "python_version >= \"3.10\""} platformdirs = ">=3.9.1,<5" -python-discovery = ">=1.3.1" +python-discovery = ">=1.4.2" typing-extensions = {version = ">=4.13.2", markers = "python_version < \"3.11\""} [[package]] name = "wcwidth" -version = "0.7.0" +version = "0.8.2" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = ">=3.8" files = [ - {file = "wcwidth-0.7.0-py3-none-any.whl", hash = "sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2"}, - {file = "wcwidth-0.7.0.tar.gz", hash = "sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0"}, + {file = "wcwidth-0.8.2-py3-none-any.whl", hash = "sha256:d63947694a0539a1d51e01eda7caf800c291020e6cdd7e28ad7b14dd33ad4f85"}, + {file = "wcwidth-0.8.2.tar.gz", hash = "sha256:91fbef97204b96a3d4d421609b80340b760cf33e26da123ff243d76b1fda8dda"}, ] [[package]] name = "wrapt" -version = "2.1.2" +version = "2.2.2" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.9" files = [ - {file = "wrapt-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b7a86d99a14f76facb269dc148590c01aaf47584071809a70da30555228158c"}, - {file = "wrapt-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a819e39017f95bf7aede768f75915635aa8f671f2993c036991b8d3bfe8dbb6f"}, - {file = "wrapt-2.1.2-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5681123e60aed0e64c7d44f72bbf8b4ce45f79d81467e2c4c728629f5baf06eb"}, - {file = "wrapt-2.1.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b8b28e97a44d21836259739ae76284e180b18abbb4dcfdff07a415cf1016c3e"}, - {file = "wrapt-2.1.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cef91c95a50596fcdc31397eb6955476f82ae8a3f5a8eabdc13611b60ee380ba"}, - {file = "wrapt-2.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dad63212b168de8569b1c512f4eac4b57f2c6934b30df32d6ee9534a79f1493f"}, - {file = "wrapt-2.1.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d307aa6888d5efab2c1cde09843d48c843990be13069003184b67d426d145394"}, - {file = "wrapt-2.1.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c87cf3f0c85e27b3ac7d9ad95da166bf8739ca215a8b171e8404a2d739897a45"}, - {file = "wrapt-2.1.2-cp310-cp310-win32.whl", hash = "sha256:d1c5fea4f9fe3762e2b905fdd67df51e4be7a73b7674957af2d2ade71a5c075d"}, - {file = "wrapt-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:d8f7740e1af13dff2684e4d56fe604a7e04d6c94e737a60568d8d4238b9a0c71"}, - {file = "wrapt-2.1.2-cp310-cp310-win_arm64.whl", hash = "sha256:1c6cc827c00dc839350155f316f1f8b4b0c370f52b6a19e782e2bda89600c7dc"}, - {file = "wrapt-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:96159a0ee2b0277d44201c3b5be479a9979cf154e8c82fa5df49586a8e7679bb"}, - {file = "wrapt-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98ba61833a77b747901e9012072f038795de7fc77849f1faa965464f3f87ff2d"}, - {file = "wrapt-2.1.2-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:767c0dbbe76cae2a60dd2b235ac0c87c9cccf4898aef8062e57bead46b5f6894"}, - {file = "wrapt-2.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c691a6bc752c0cc4711cc0c00896fcd0f116abc253609ef64ef930032821842"}, - {file = "wrapt-2.1.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f3b7d73012ea75aee5844de58c88f44cf62d0d62711e39da5a82824a7c4626a8"}, - {file = "wrapt-2.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:577dff354e7acd9d411eaf4bfe76b724c89c89c8fc9b7e127ee28c5f7bcb25b6"}, - {file = "wrapt-2.1.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3d7b6fd105f8b24e5bd23ccf41cb1d1099796524bcc6f7fbb8fe576c44befbc9"}, - {file = "wrapt-2.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:866abdbf4612e0b34764922ef8b1c5668867610a718d3053d59e24a5e5fcfc15"}, - {file = "wrapt-2.1.2-cp311-cp311-win32.whl", hash = "sha256:5a0a0a3a882393095573344075189eb2d566e0fd205a2b6414e9997b1b800a8b"}, - {file = "wrapt-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:64a07a71d2730ba56f11d1a4b91f7817dc79bc134c11516b75d1921a7c6fcda1"}, - {file = "wrapt-2.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:b89f095fe98bc12107f82a9f7d570dc83a0870291aeb6b1d7a7d35575f55d98a"}, - {file = "wrapt-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ff2aad9c4cda28a8f0653fc2d487596458c2a3f475e56ba02909e950a9efa6a9"}, - {file = "wrapt-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6433ea84e1cfacf32021d2a4ee909554ade7fd392caa6f7c13f1f4bf7b8e8748"}, - {file = "wrapt-2.1.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c20b757c268d30d6215916a5fa8461048d023865d888e437fab451139cad6c8e"}, - {file = "wrapt-2.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79847b83eb38e70d93dc392c7c5b587efe65b3e7afcc167aa8abd5d60e8761c8"}, - {file = "wrapt-2.1.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f8fba1bae256186a83d1875b2b1f4e2d1242e8fac0f58ec0d7e41b26967b965c"}, - {file = "wrapt-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e3d3b35eedcf5f7d022291ecd7533321c4775f7b9cd0050a31a68499ba45757c"}, - {file = "wrapt-2.1.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:6f2c5390460de57fa9582bc8a1b7a6c86e1a41dfad74c5225fc07044c15cc8d1"}, - {file = "wrapt-2.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7dfa9f2cf65d027b951d05c662cc99ee3bd01f6e4691ed39848a7a5fffc902b2"}, - {file = "wrapt-2.1.2-cp312-cp312-win32.whl", hash = "sha256:eba8155747eb2cae4a0b913d9ebd12a1db4d860fc4c829d7578c7b989bd3f2f0"}, - {file = "wrapt-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1c51c738d7d9faa0b3601708e7e2eda9bf779e1b601dce6c77411f2a1b324a63"}, - {file = "wrapt-2.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:c8e46ae8e4032792eb2f677dbd0d557170a8e5524d22acc55199f43efedd39bf"}, - {file = "wrapt-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787fd6f4d67befa6fe2abdffcbd3de2d82dfc6fb8a6d850407c53332709d030b"}, - {file = "wrapt-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4bdf26e03e6d0da3f0e9422fd36bcebf7bc0eeb55fdf9c727a09abc6b9fe472e"}, - {file = "wrapt-2.1.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bbac24d879aa22998e87f6b3f481a5216311e7d53c7db87f189a7a0266dafffb"}, - {file = "wrapt-2.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16997dfb9d67addc2e3f41b62a104341e80cac52f91110dece393923c0ebd5ca"}, - {file = "wrapt-2.1.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:162e4e2ba7542da9027821cb6e7c5e068d64f9a10b5f15512ea28e954893a267"}, - {file = "wrapt-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f29c827a8d9936ac320746747a016c4bc66ef639f5cd0d32df24f5eacbf9c69f"}, - {file = "wrapt-2.1.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:a9dd9813825f7ecb018c17fd147a01845eb330254dff86d3b5816f20f4d6aaf8"}, - {file = "wrapt-2.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f8dbdd3719e534860d6a78526aafc220e0241f981367018c2875178cf83a413"}, - {file = "wrapt-2.1.2-cp313-cp313-win32.whl", hash = "sha256:5c35b5d82b16a3bc6e0a04349b606a0582bc29f573786aebe98e0c159bc48db6"}, - {file = "wrapt-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f8bc1c264d8d1cf5b3560a87bbdd31131573eb25f9f9447bb6252b8d4c44a3a1"}, - {file = "wrapt-2.1.2-cp313-cp313-win_arm64.whl", hash = "sha256:3beb22f674550d5634642c645aba4c72a2c66fb185ae1aebe1e955fae5a13baf"}, - {file = "wrapt-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fc04bc8664a8bc4c8e00b37b5355cffca2535209fba1abb09ae2b7c76ddf82b"}, - {file = "wrapt-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a9b9d50c9af998875a1482a038eb05755dfd6fe303a313f6a940bb53a83c3f18"}, - {file = "wrapt-2.1.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2d3ff4f0024dd224290c0eabf0240f1bfc1f26363431505fb1b0283d3b08f11d"}, - {file = "wrapt-2.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3278c471f4468ad544a691b31bb856374fbdefb7fee1a152153e64019379f015"}, - {file = "wrapt-2.1.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8914c754d3134a3032601c6984db1c576e6abaf3fc68094bb8ab1379d75ff92"}, - {file = "wrapt-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ff95d4264e55839be37bafe1536db2ab2de19da6b65f9244f01f332b5286cfbf"}, - {file = "wrapt-2.1.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:76405518ca4e1b76fbb1b9f686cff93aebae03920cc55ceeec48ff9f719c5f67"}, - {file = "wrapt-2.1.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c0be8b5a74c5824e9359b53e7e58bef71a729bacc82e16587db1c4ebc91f7c5a"}, - {file = "wrapt-2.1.2-cp313-cp313t-win32.whl", hash = "sha256:f01277d9a5fc1862f26f7626da9cf443bebc0abd2f303f41c5e995b15887dabd"}, - {file = "wrapt-2.1.2-cp313-cp313t-win_amd64.whl", hash = "sha256:84ce8f1c2104d2f6daa912b1b5b039f331febfeee74f8042ad4e04992bd95c8f"}, - {file = "wrapt-2.1.2-cp313-cp313t-win_arm64.whl", hash = "sha256:a93cd767e37faeddbe07d8fc4212d5cba660af59bdb0f6372c93faaa13e6e679"}, - {file = "wrapt-2.1.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1370e516598854e5b4366e09ce81e08bfe94d42b0fd569b88ec46cc56d9164a9"}, - {file = "wrapt-2.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6de1a3851c27e0bd6a04ca993ea6f80fc53e6c742ee1601f486c08e9f9b900a9"}, - {file = "wrapt-2.1.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:de9f1a2bbc5ac7f6012ec24525bdd444765a2ff64b5985ac6e0692144838542e"}, - {file = "wrapt-2.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:970d57ed83fa040d8b20c52fe74a6ae7e3775ae8cff5efd6a81e06b19078484c"}, - {file = "wrapt-2.1.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3969c56e4563c375861c8df14fa55146e81ac11c8db49ea6fb7f2ba58bc1ff9a"}, - {file = "wrapt-2.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:57d7c0c980abdc5f1d98b11a2aa3bb159790add80258c717fa49a99921456d90"}, - {file = "wrapt-2.1.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:776867878e83130c7a04237010463372e877c1c994d449ca6aaafeab6aab2586"}, - {file = "wrapt-2.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fab036efe5464ec3291411fabb80a7a39e2dd80bae9bcbeeca5087fdfa891e19"}, - {file = "wrapt-2.1.2-cp314-cp314-win32.whl", hash = "sha256:e6ed62c82ddf58d001096ae84ce7f833db97ae2263bff31c9b336ba8cfe3f508"}, - {file = "wrapt-2.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:467e7c76315390331c67073073d00662015bb730c566820c9ca9b54e4d67fd04"}, - {file = "wrapt-2.1.2-cp314-cp314-win_arm64.whl", hash = "sha256:da1f00a557c66225d53b095a97eace0fc5349e3bfda28fa34ffae238978ee575"}, - {file = "wrapt-2.1.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:62503ffbc2d3a69891cf29beeaccdb4d5e0a126e2b6a851688d4777e01428dbb"}, - {file = "wrapt-2.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c7e6cd120ef837d5b6f860a6ea3745f8763805c418bb2f12eeb1fa6e25f22d22"}, - {file = "wrapt-2.1.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3769a77df8e756d65fbc050333f423c01ae012b4f6731aaf70cf2bef61b34596"}, - {file = "wrapt-2.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a76d61a2e851996150ba0f80582dd92a870643fa481f3b3846f229de88caf044"}, - {file = "wrapt-2.1.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6f97edc9842cf215312b75fe737ee7c8adda75a89979f8e11558dfff6343cc4b"}, - {file = "wrapt-2.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4006c351de6d5007aa33a551f600404ba44228a89e833d2fadc5caa5de8edfbf"}, - {file = "wrapt-2.1.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a9372fc3639a878c8e7d87e1556fa209091b0a66e912c611e3f833e2c4202be2"}, - {file = "wrapt-2.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3144b027ff30cbd2fca07c0a87e67011adb717eb5f5bd8496325c17e454257a3"}, - {file = "wrapt-2.1.2-cp314-cp314t-win32.whl", hash = "sha256:3b8d15e52e195813efe5db8cec156eebe339aaf84222f4f4f051a6c01f237ed7"}, - {file = "wrapt-2.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:08ffa54146a7559f5b8df4b289b46d963a8e74ed16ba3687f99896101a3990c5"}, - {file = "wrapt-2.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:72aaa9d0d8e4ed0e2e98019cea47a21f823c9dd4b43c7b77bba6679ffcca6a00"}, - {file = "wrapt-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5e0fa9cc32300daf9eb09a1f5bdc6deb9a79defd70d5356ba453bcd50aef3742"}, - {file = "wrapt-2.1.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:710f6e5dfaf6a5d5c397d2d6758a78fecd9649deb21f1b645f5b57a328d63050"}, - {file = "wrapt-2.1.2-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:305d8a1755116bfdad5dda9e771dcb2138990a1d66e9edd81658816edf51aed1"}, - {file = "wrapt-2.1.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f0d8fc30a43b5fe191cf2b1a0c82bab2571dadd38e7c0062ee87d6df858dd06e"}, - {file = "wrapt-2.1.2-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a5d516e22aedb7c9c1d47cba1c63160b1a6f61ec2f3948d127cd38d5cfbb556f"}, - {file = "wrapt-2.1.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:45914e8efbe4b9d5102fcf0e8e2e3258b83a5d5fba9f8f7b6d15681e9d29ffe0"}, - {file = "wrapt-2.1.2-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:478282ebd3795a089154fb16d3db360e103aa13d3b2ad30f8f6aac0d2207de0e"}, - {file = "wrapt-2.1.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3756219045f73fb28c5d7662778e4156fbd06cf823c4d2d4b19f97305e52819c"}, - {file = "wrapt-2.1.2-cp39-cp39-win32.whl", hash = "sha256:b8aefb4dbb18d904b96827435a763fa42fc1f08ea096a391710407a60983ced8"}, - {file = "wrapt-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:e5aeab8fe15c3dff75cfee94260dcd9cded012d4ff06add036c28fae7718593b"}, - {file = "wrapt-2.1.2-cp39-cp39-win_arm64.whl", hash = "sha256:f069e113743a21a3defac6677f000068ebb931639f789b5b226598e247a4c89e"}, - {file = "wrapt-2.1.2-py3-none-any.whl", hash = "sha256:b8fd6fa2b2c4e7621808f8c62e8317f4aae56e59721ad933bac5239d913cf0e8"}, - {file = "wrapt-2.1.2.tar.gz", hash = "sha256:3996a67eecc2c68fd47b4e3c564405a5777367adfd9b8abb58387b63ee83b21e"}, + {file = "wrapt-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:055e6fcfaa28e58c6a8c247d48b92be9d56f818b7068aa4f22b15b3343a09931"}, + {file = "wrapt-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8374eb6b1a58809211e84ff835a182bb17ab2807a5bfef23204c8cff38178a00"}, + {file = "wrapt-2.2.2-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:656593bb3f5529f03d27af4136c4d7b11990e470bcbc6fefa5ef218695bece55"}, + {file = "wrapt-2.2.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfb00cb7bb22099e2f64b7340fb96113639aa7260c0972af3797ace2297b936c"}, + {file = "wrapt-2.2.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e7f10ee0bd53673bfd52b67cbce83336fe6cad90d2377b03baf66491d2bbfb91"}, + {file = "wrapt-2.2.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4402f57c5f0d0579599858ffbdd9bf4e3f0972f51096f2bd6cc7dab6b76ee49e"}, + {file = "wrapt-2.2.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:3a4eb7964ff4643d333c84f880bcf554652b2a1050aebc54ae696327f61acfaf"}, + {file = "wrapt-2.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e542b7c5af91e2123a8aabf19894319d5ec4268d2a9ffd2f239386133fc47746"}, + {file = "wrapt-2.2.2-cp310-cp310-win32.whl", hash = "sha256:6e7e45b43d3c774d244fe7264378f5a3f0f383bc55a54a9866434e524540110f"}, + {file = "wrapt-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:955f1d6e72a352e478de8d8b503abe301c5e139a141b62eb0923bd694995025f"}, + {file = "wrapt-2.2.2-cp310-cp310-win_arm64.whl", hash = "sha256:b89d8d73c82db2bb7e6090b3afd7973f980d24e905cc34394eab60b884b3bf67"}, + {file = "wrapt-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f1a2ff355ece6a111ca7a20dc86df6659c9205d3fcee674ca34f2a2854fd4e73"}, + {file = "wrapt-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:55b9a899e6fff5444f229d30aa6e9ac92d2216d9d60f33c771b5d76a760d5f8e"}, + {file = "wrapt-2.2.2-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a2d78c363f97d8bd718ee40432c66395685e9e98528ccaa423c3355d1715a26d"}, + {file = "wrapt-2.2.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d619e1eed9bd4f6ed9f24cd61971aa086fa86505289628d464bcf8a2c2e3f328"}, + {file = "wrapt-2.2.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:518b0c5e323511ec56a38894802ddd5e1222626484e68efe63f201854ad788e5"}, + {file = "wrapt-2.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4bccea5cdecffa9dd70e343741f0e41e0a16619313d04b72f78bb525162ebcd0"}, + {file = "wrapt-2.2.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:209112cafd963710a05d199aae431d79a28bc76eb8e6d1bbbb8ad24340722cae"}, + {file = "wrapt-2.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e5a5290e4bf2f332fc29ce72ffb9a2fff678aaac047e2e9f5f7165cd7792e099"}, + {file = "wrapt-2.2.2-cp311-cp311-win32.whl", hash = "sha256:5499236ad1dc116012e2a5dd943f3f31af12fce452128e2bbcbd55a7d3d4d14c"}, + {file = "wrapt-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:8636809939152be6ae20a6cef0fed9fe60f411b47847d0426a826884b469e971"}, + {file = "wrapt-2.2.2-cp311-cp311-win_arm64.whl", hash = "sha256:5d0a142f7af07caeb5e5da87493162a7b8efa19ba919e550a746f7446e13fb30"}, + {file = "wrapt-2.2.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8417fd3c674d3c8023d080292d29301531a12daf8bd938dd419710dd2f464f2b"}, + {file = "wrapt-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e7070c7472582e31af3dfc2622b2381a0df7435110a9388ed8db5ffbce67efb"}, + {file = "wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2e096c9d39a59b35b63c9aacfbbbec2088ff51ff1fc31051acc60a07f42f273a"}, + {file = "wrapt-2.2.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d1a6050405bf334be33bf66296f113563622972a34900ae6fa60fd283a1a900"}, + {file = "wrapt-2.2.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:10adb01371408c6de504a6658b9886480f1a4919a83752748a387a504a21df79"}, + {file = "wrapt-2.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3442eee2a5798f9b451f1b2cd7518ce8b7e28a2a364696c414460a0e295c012a"}, + {file = "wrapt-2.2.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:6c99012a22f735a85eed7c4b86a3e99c30fdd57d9e115b2b45f796264b58d0bf"}, + {file = "wrapt-2.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3b686cfc008776a3952d6213cb296ed7f45d782a8453936406faa89eac0835ab"}, + {file = "wrapt-2.2.2-cp312-cp312-win32.whl", hash = "sha256:ef2cce266b5b0b07e19fa82e59673b81142b7a3607c8ed1254113d048ed668da"}, + {file = "wrapt-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:abf8c20a2d72ee69e16328b3c91342c446e723bfe48bfcc4dded3b9722ac027f"}, + {file = "wrapt-2.2.2-cp312-cp312-win_arm64.whl", hash = "sha256:c6c64c5d02578bc4c4bca4f0aef1504de933c1d5b4ac2710b9131111459506c8"}, + {file = "wrapt-2.2.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9e8b648270c613720a202d9a45ebabc33261b22c3a839b115ac5bce8c0bb0d69"}, + {file = "wrapt-2.2.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6fb7e94e8fe3e4c3067bb1653a91cce7c5e83acc119fdd41501b1bf74654617"}, + {file = "wrapt-2.2.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb18fc51e813df0d9c98049e3bf2298a5495a648602040e21fa3c7329371159e"}, + {file = "wrapt-2.2.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94b00b00f806eb3ef2abe9049ed45994a81ee9284884d96e6b8314927c6cea3d"}, + {file = "wrapt-2.2.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:62415fd095bc590b842b6d092f2b5d9ccbaeb7e0b28535c03dcea2718b48636b"}, + {file = "wrapt-2.2.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a41e758d80dc0ab8c210f641ac892009d356cf1f955d97db544c8dd317b4d14c"}, + {file = "wrapt-2.2.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b84cd4058001c9727b0e9980b7a9e66325b5ca748b1b578e822cade1bc6b304f"}, + {file = "wrapt-2.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26fc73a1b15e0946d2942b9a4426d162b51676338327dc067ccd8d2d76385f94"}, + {file = "wrapt-2.2.2-cp313-cp313-win32.whl", hash = "sha256:3c4095803491f6ef72128914c28ec05bbad9758433bb35f6715a3e9c8e46fb2d"}, + {file = "wrapt-2.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:2cb07f414fab25dbe6b5c7398e1491423a5c81a6209533639969a6c928d474a4"}, + {file = "wrapt-2.2.2-cp313-cp313-win_arm64.whl", hash = "sha256:1fc7691f070220215cccb2a20836b9adbaecb8ff22ad47abe63de5f110994fac"}, + {file = "wrapt-2.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ec8f83949028366531383603139403cac7a826e4011955813cdd640017845ce5"}, + {file = "wrapt-2.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4b481fb0c40d9fd90a5809911208da700987d373a20a4709dc9e3944af7a6bec"}, + {file = "wrapt-2.2.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0065a3b657cec06813b4241d2462ccec287f6863103d7445b725fb3a889736f9"}, + {file = "wrapt-2.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30f7424af5c5c345b7f26490e097f74a2ef45b3d08b664dc33571aee3bd3b56c"}, + {file = "wrapt-2.2.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:07fdcb012821859168641acf68afad61ef9783cf37100af85f152550e9677194"}, + {file = "wrapt-2.2.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f90038ab58fafb584801ca62d72384d7d5225d93c76f7b773c22fae545bd8066"}, + {file = "wrapt-2.2.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:c5d7825491bfa2d08b97e9557768987952c7b9ae687d06c3320b40a37ccb7f20"}, + {file = "wrapt-2.2.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0ad520e6daa9bbf136f14de735474dbec7dcc0891f718e1d274ce8dc92e645af"}, + {file = "wrapt-2.2.2-cp313-cp313t-win32.whl", hash = "sha256:25904acb9475f46c24fe0423dbc8fda8cc5fbc282ab3dc6e72e919748c53f4e9"}, + {file = "wrapt-2.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:305d4c247d61c4115794a169141823c62f719525ddb90b23aa332741c77d2c28"}, + {file = "wrapt-2.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:c20279cd1a29800815d7b2d6338b60a6c6e78263f9d6e62e0eda251ba9cae2d0"}, + {file = "wrapt-2.2.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0e64826f920c42d9d9f87e8cc09ffae66c51ede12d59061a5a426deb9aa71745"}, + {file = "wrapt-2.2.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:dcaa5e1451bd8751d7bd1568dfa3321c78092a52a7ecb5d1a0f18a5791e1fd00"}, + {file = "wrapt-2.2.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0abfd648dac9ac9c5b3aa9b523d27f1789046640b58dcd5652a720ddb325e1fc"}, + {file = "wrapt-2.2.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f4bfd8d1eb438153eff8b8cfe87f032ba65731e1ce06138b5090f745a33f6f95"}, + {file = "wrapt-2.2.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c427c9d06d859848a69f0d928fe28b5c33a941b2265d10a0e1f15cd244f1ee33"}, + {file = "wrapt-2.2.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4250b43d1a129d947e083c4dc6baf333c9bb34edd26f912d5b0457841fc858ab"}, + {file = "wrapt-2.2.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:173e5bb5ca350a6e0abab60b7ec7cdd7992a814cb14b4de670a28f067f105663"}, + {file = "wrapt-2.2.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:aa14b01804bce36c6d63d7b6a4f55df390f29f8648cc13a1f40b166f4d54680d"}, + {file = "wrapt-2.2.2-cp314-cp314-win32.whl", hash = "sha256:58f9f8d637c9a6e245c6ef5b109b67ec187d2faed23d1405656b51d96e0a5b56"}, + {file = "wrapt-2.2.2-cp314-cp314-win_amd64.whl", hash = "sha256:385cb1866f20479e83299af585375bfa0a4b0c6c9907a981483ea782ea8ae406"}, + {file = "wrapt-2.2.2-cp314-cp314-win_arm64.whl", hash = "sha256:8ffbeaea6771a6eba6e6eeb09767864995726bc8240bb54baf88a9bb1db34d5c"}, + {file = "wrapt-2.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:09f811d43f6f33ec7515f0be76b159569f4057ab54d3e079c3204dddb90afa2a"}, + {file = "wrapt-2.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a795d3c06e5fbf9ea2f13196180b77aeab1b4685917256ee0d014cc163d90063"}, + {file = "wrapt-2.2.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:45c2f2768e790c9f8db90f239ef23a2af8e7570f25a35619ef902df4a738447f"}, + {file = "wrapt-2.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbf00ee0cb55ec24e2b0995a71942b85b21a066db8f3f46e1dbfdb9433ffba81"}, + {file = "wrapt-2.2.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2252f77663651b89255895f58cc6ac08fcb206d4371813e5af61bb62d4f7689c"}, + {file = "wrapt-2.2.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2cd7181ab1c31192ff5219269830744b5a62020b3a6d433588c4f1c95b8f8bff"}, + {file = "wrapt-2.2.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:6fe35fd51b74867d8b80174c277bd6bbf6a73e443f908129dc531c4b688a20d5"}, + {file = "wrapt-2.2.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:11d95fc2fbad3163596c39d440e6f21ca9fccece74b56e30a37ac2fca786a07c"}, + {file = "wrapt-2.2.2-cp314-cp314t-win32.whl", hash = "sha256:d8a15813215f33fa83667bfc978b300e35669ea8bb424e970a1426bcb7bc6cca"}, + {file = "wrapt-2.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:d09db0f7e8357060d3c38fc22a018aba683a796bf184360fd1a58f6fc180dc77"}, + {file = "wrapt-2.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:f32fe639c39561ccc187bcae17e9271be0eb45f1c2952510d2f29b33ab577347"}, + {file = "wrapt-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d01d8e0afc55823245a3b97a79c7c77464e31ea7a7b629a4bf26f9441dc1f18e"}, + {file = "wrapt-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a28287413351cb198b8c5ddd045c56fac1d195808642cd264d1ab50426146650"}, + {file = "wrapt-2.2.2-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:abf033b7e4542357659cd83ed6cd5033c43aaa1887044045ceb571528837f72f"}, + {file = "wrapt-2.2.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d2f6573561fa05002e5ee71529f4ab0a7dffed3e45b51013fe6298fe2723c02"}, + {file = "wrapt-2.2.2-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c38510a21d5b9cf3e84c460d909e9f2a098667439fd42841bb081cab45835d68"}, + {file = "wrapt-2.2.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cd385a48b055bdc3630ab30e0c7fd8514a36904ec23f9cee7a65d887334a3cea"}, + {file = "wrapt-2.2.2-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:3dc3dcfc2da95d501905f10dc11a0dc622e91d8cdd8bbfcb63ca54afd131e556"}, + {file = "wrapt-2.2.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:fa81c5b5fe8cd6c41e3a798533b81288279e5fdbde2128f21071922764281c99"}, + {file = "wrapt-2.2.2-cp39-cp39-win32.whl", hash = "sha256:814f1bf3e0a7035f67a1db0cdaf5e2bbcaa4d7092db96673cfa467adeaab8591"}, + {file = "wrapt-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:9ee098171b07edba66ab69a9bf0251d3cbef654107e800feb24c0c6f30592728"}, + {file = "wrapt-2.2.2-cp39-cp39-win_arm64.whl", hash = "sha256:3179a4db066b53d40562e368b12895440c8f0953b6543b89d6acc41c0273996e"}, + {file = "wrapt-2.2.2-py3-none-any.whl", hash = "sha256:5bad217350f19ce99ca5b5e71d406765ea86fe541628426772b657375ee1c048"}, + {file = "wrapt-2.2.2.tar.gz", hash = "sha256:0788e321027c999bf221b667bd4a54aaefd1a36283749a860ac3eb77daed0302"}, ] [package.extras] @@ -3038,4 +3174,4 @@ docs = ["sphinx-rtd-theme", "sphinxcontrib-napoleon"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.14" -content-hash = "e89f757d54ff2a3b3dfcfde7342b55e1394c114c7db337dcd8bc9a7c9dea37c1" +content-hash = "d852b1b12c47dda0efb2548c8427cc29d673899b820075a7c87bb64585b3836b" diff --git a/pyproject.toml b/pyproject.toml index b36b5dc4..9658cc80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "datafaker" -version = "0.4.0" +version = "0.5.0" description = "Generates fake SQL data" authors = ["Tim Band <3266052+tim-band@users.noreply.github.com>"] license = "MIT" @@ -18,6 +18,8 @@ homepage = "https://github.com/SAFEHR-data/datafaker" python = ">=3.10,<3.14" pydantic = {extras = ["dotenv"], version = "^1.10.2"} psycopg2-binary = "^2.9.5" +pyodbc = "^5.0.0" +aioodbc = "^0.5.0" sqlalchemy-utils = "^0.41.2" mimesis = "^18.0.0" typer = "^0.15.4" @@ -53,7 +55,8 @@ testing-postgresql = "^1.3.0" duckdb = "^1.4.3" sphinx-rtd-theme = "^1.2.0" sphinxcontrib-napoleon = "^0.7" -sphinxcontrib-mermaid = "^2.0.0" +sphinxcontrib-mermaid = "2.0.3" +pytest = "^9.0.3" [tool.poetry.group.extras.dependencies] tqdm = "^4.65.0" diff --git a/tests/examples/example_config2.yaml b/tests/examples/example_config2.yaml index 4fbea1a1..e119fa85 100644 --- a/tests/examples/example_config2.yaml +++ b/tests/examples/example_config2.yaml @@ -45,7 +45,7 @@ src-stats: - All the values and their counts that appear in column visit_type_concept_id of table hospital_visit query: > SELECT visit_type_concept_id AS value, COUNT(visit_type_concept_id) AS count FROM hospital_visit - WHERE visit_type_concept_id IS NOT NULL GROUP BY value + WHERE visit_type_concept_id IS NOT NULL GROUP BY visit_type_concept_id ORDER BY COUNT(visit_type_concept_id) DESC max-unique-constraint-tries: 50 diff --git a/tests/examples/instrument.sql b/tests/examples/instrument.sql index 747e9431..4dbdbca8 100644 --- a/tests/examples/instrument.sql +++ b/tests/examples/instrument.sql @@ -14,8 +14,8 @@ ALTER TABLE ONLY public.manufacturer ADD CONSTRAINT manufacturer_pkey PRIMARY KE ALTER TABLE public.manufacturer OWNER TO postgres; -INSERT INTO public.manufacturer VALUES (1, 'Blender', 'January 8 04:05:06 1951 PST'); -INSERT INTO public.manufacturer VALUES (2, 'Gibbs', 'March 4 07:08:09 1959 PST'); +INSERT INTO public.manufacturer VALUES (1, 'Blender', '1951-01-08 12:05:06+00:00'); +INSERT INTO public.manufacturer VALUES (2, 'Gibbs', '1959-03-04 15:08:09+00:00'); CREATE TABLE public.model ( id INTEGER NOT NULL, @@ -30,9 +30,9 @@ ALTER TABLE ONLY public.model ALTER TABLE public.model OWNER TO postgres; -INSERT INTO public.model VALUES (1, 'S-Type', 1, 'April 20 04:05:06 1952 PST'); -INSERT INTO public.model VALUES (2, 'Pulse', 1, 'December 2 02:15:06 1953 PST'); -INSERT INTO public.model VALUES (3, 'Paul Leslie', 2, 'February 20 04:05:06 1960 PST'); +INSERT INTO public.model VALUES (1, 'S-Type', 1, '1952-04-20 04:05:06+00:00'); +INSERT INTO public.model VALUES (2, 'Pulse', 1, '1953-12-02 02:15:06+00:00'); +INSERT INTO public.model VALUES (3, 'Paul Leslie', 2, '1960-02-20 04:05:06+00:00'); CREATE TABLE public.string ( id INTEGER NOT NULL, diff --git a/tests/examples/src.dump b/tests/examples/src.dump index 3f982ac6..97f5288c 100644 --- a/tests/examples/src.dump +++ b/tests/examples/src.dump @@ -234,8 +234,8 @@ ALTER TABLE public.strange_type_table OWNER TO postgres; -- Data for Name: concept; Type: TABLE DATA; Schema: public; Owner: postgres -- -INSERT INTO public.concept VALUES (1, 'some concept name', 1, 'January 8 04:05:06 1999 PST'); -INSERT INTO public.concept VALUES (23, 'another concept', 2, 'January 8 04:05:06 1999 PST'); +INSERT INTO public.concept VALUES (1, 'some concept name', 1, '1999-01-08 04:05:06+00:00'); +INSERT INTO public.concept VALUES (23, 'another concept', 2, '1999-01-08 04:05:06+00:00'); -- @@ -271,1006 +271,1006 @@ INSERT INTO public.mitigation_type VALUES (2, 'panic', 'don''t hold back, flail -- Data for Name: person; Type: TABLE DATA; Schema: public; Owner: postgres -- -INSERT INTO public.person VALUES (1, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (2, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (3, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (4, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (5, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (6, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (7, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (8, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (9, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (10, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (11, 'Testfried Testermann', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (12, 'Veronica Fyre', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (13, 'Miranda Rando-Generata', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (14, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (15, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (16, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (17, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (18, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (19, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (20, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (21, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (22, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (23, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (24, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (25, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (26, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (27, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (28, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (29, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (30, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (31, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (32, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (33, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (34, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (35, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (36, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (37, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (38, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (39, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (40, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (41, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (42, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (43, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (44, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (45, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (46, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (47, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (48, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (49, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (50, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (51, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (52, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (53, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (54, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (55, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (56, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (57, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (58, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (59, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (60, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (61, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (62, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (63, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (64, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (65, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (66, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (67, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (68, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (69, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (70, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (71, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (72, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (73, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (74, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (75, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (76, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (77, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (78, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (79, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (80, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (81, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (82, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (83, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (84, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (85, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (86, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (87, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (88, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (89, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (90, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (91, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (92, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (93, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (94, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (95, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (96, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (97, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (98, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (99, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (100, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (101, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (102, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (103, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (104, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (105, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (106, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (107, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (108, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (109, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (110, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (111, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (112, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (113, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (114, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (115, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (116, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (117, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (118, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (119, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (120, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (121, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (122, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (123, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (124, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (125, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (126, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (127, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (128, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (129, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (130, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (131, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (132, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (133, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (134, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (135, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (136, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (137, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (138, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (139, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (140, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (141, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (142, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (143, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (144, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (145, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (146, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (147, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (148, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (149, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (150, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (151, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (152, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (153, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (154, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (155, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (156, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (157, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (158, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (159, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (160, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (161, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (162, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (163, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (164, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (165, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (166, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (167, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (168, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (169, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (170, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (171, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (172, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (173, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (174, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (175, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (176, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (177, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (178, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (179, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (180, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (181, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (182, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (183, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (184, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (185, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (186, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (187, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (188, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (189, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (190, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (191, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (192, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (193, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (194, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (195, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (196, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (197, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (198, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (199, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (200, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (201, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (202, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (203, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (204, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (205, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (206, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (207, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (208, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (209, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (210, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (211, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (212, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (213, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (214, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (215, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (216, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (217, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (218, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (219, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (220, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (221, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (222, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (223, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (224, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (225, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (226, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (227, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (228, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (229, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (230, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (231, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (232, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (233, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (234, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (235, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (236, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (237, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (238, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (239, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (240, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (241, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (242, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (243, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (244, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (245, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (246, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (247, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (248, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (249, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (250, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (251, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (252, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (253, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (254, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (255, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (256, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (257, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (258, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (259, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (260, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (261, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (262, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (263, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (264, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (265, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (266, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (267, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (268, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (269, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (270, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (271, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (272, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (273, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (274, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (275, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (276, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (277, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (278, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (279, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (280, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (281, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (282, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (283, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (284, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (285, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (286, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (287, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (288, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (289, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (290, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (291, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (292, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (293, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (294, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (295, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (296, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (297, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (298, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (299, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (300, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (301, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (302, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (303, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (304, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (305, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (306, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (307, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (308, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (309, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (310, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (311, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (312, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (313, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (314, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (315, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (316, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (317, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (318, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (319, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (320, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (321, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (322, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (323, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (324, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (325, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (326, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (327, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (328, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (329, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (330, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (331, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (332, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (333, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (334, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (335, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (336, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (337, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (338, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (339, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (340, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (341, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (342, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (343, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (344, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (345, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (346, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (347, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (348, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (349, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (350, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (351, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (352, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (353, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (354, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (355, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (356, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (357, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (358, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (359, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (360, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (361, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (362, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (363, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (364, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (365, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (366, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (367, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (368, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (369, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (370, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (371, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (372, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (373, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (374, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (375, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (376, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (377, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (378, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (379, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (380, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (381, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (382, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (383, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (384, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (385, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (386, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (387, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (388, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (389, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (390, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (391, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (392, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (393, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (394, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (395, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (396, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (397, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (398, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (399, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (400, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (401, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (402, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (403, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (404, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (405, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (406, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (407, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (408, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (409, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (410, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (411, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (412, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (413, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (414, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (415, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (416, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (417, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (418, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (419, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (420, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (421, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (422, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (423, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (424, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (425, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (426, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (427, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (428, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (429, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (430, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (431, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (432, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (433, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (434, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (435, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (436, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (437, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (438, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (439, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (440, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (441, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (442, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (443, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (444, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (445, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (446, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (447, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (448, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (449, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (450, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (451, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (452, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (453, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (454, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (455, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (456, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (457, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (458, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (459, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (460, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (461, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (462, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (463, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (464, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (465, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (466, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (467, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (468, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (469, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (470, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (471, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (472, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (473, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (474, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (475, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (476, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (477, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (478, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (479, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (480, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (481, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (482, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (483, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (484, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (485, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (486, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (487, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (488, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (489, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (490, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (491, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (492, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (493, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (494, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (495, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (496, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (497, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (498, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (499, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (500, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (501, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (502, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (503, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (504, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (505, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (506, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (507, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (508, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (509, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (510, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (511, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (512, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (513, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (514, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (515, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (516, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (517, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (518, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (519, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (520, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (521, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (522, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (523, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (524, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (525, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (526, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (527, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (528, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (529, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (530, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (531, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (532, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (533, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (534, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (535, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (536, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (537, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (538, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (539, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (540, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (541, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (542, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (543, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (544, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (545, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (546, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (547, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (548, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (549, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (550, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (551, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (552, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (553, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (554, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (555, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (556, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (557, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (558, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (559, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (560, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (561, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (562, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (563, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (564, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (565, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (566, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (567, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (568, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (569, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (570, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (571, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (572, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (573, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (574, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (575, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (576, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (577, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (578, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (579, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (580, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (581, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (582, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (583, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (584, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (585, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (586, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (587, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (588, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (589, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (590, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (591, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (592, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (593, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (594, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (595, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (596, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (597, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (598, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (599, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (600, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (601, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (602, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (603, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (604, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (605, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (606, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (607, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (608, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (609, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (610, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (611, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (612, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (613, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (614, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (615, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (616, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (617, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (618, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (619, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (620, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (621, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (622, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (623, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (624, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (625, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (626, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (627, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (628, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (629, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (630, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (631, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (632, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (633, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (634, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (635, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (636, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (637, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (638, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (639, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (640, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (641, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (642, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (643, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (644, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (645, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (646, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (647, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (648, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (649, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (650, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (651, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (652, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (653, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (654, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (655, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (656, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (657, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (658, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (659, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (660, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (661, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (662, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (663, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (664, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (665, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (666, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (667, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (668, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (669, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (670, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (671, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (672, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (673, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (674, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (675, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (676, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (677, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (678, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (679, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (680, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (681, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (682, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (683, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (684, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (685, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (686, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (687, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (688, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (689, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (690, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (691, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (692, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (693, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (694, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (695, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (696, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (697, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (698, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (699, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (700, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (701, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (702, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (703, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (704, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (705, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (706, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (707, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (708, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (709, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (710, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (711, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (712, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (713, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (714, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (715, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (716, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (717, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (718, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (719, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (720, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (721, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (722, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (723, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (724, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (725, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (726, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (727, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (728, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (729, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (730, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (731, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (732, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (733, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (734, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (735, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (736, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (737, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (738, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (739, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (740, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (741, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (742, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (743, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (744, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (745, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (746, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (747, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (748, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (749, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (750, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (751, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (752, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (753, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (754, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (755, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (756, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (757, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (758, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (759, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (760, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (761, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (762, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (763, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (764, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (765, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (766, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (767, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (768, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (769, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (770, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (771, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (772, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (773, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (774, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (775, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (776, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (777, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (778, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (779, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (780, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (781, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (782, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (783, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (784, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (785, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (786, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (787, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (788, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (789, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (790, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (791, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (792, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (793, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (794, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (795, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (796, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (797, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (798, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (799, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (800, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (801, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (802, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (803, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (804, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (805, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (806, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (807, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (808, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (809, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (810, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (811, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (812, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (813, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (814, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (815, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (816, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (817, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (818, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (819, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (820, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (821, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (822, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (823, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (824, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (825, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (826, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (827, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (828, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (829, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (830, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (831, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (832, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (833, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (834, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (835, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (836, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (837, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (838, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (839, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (840, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (841, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (842, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (843, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (844, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (845, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (846, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (847, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (848, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (849, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (850, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (851, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (852, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (853, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (854, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (855, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (856, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (857, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (858, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (859, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (860, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (861, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (862, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (863, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (864, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (865, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (866, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (867, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (868, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (869, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (870, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (871, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (872, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (873, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (874, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (875, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (876, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (877, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (878, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (879, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (880, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (881, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (882, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (883, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (884, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (885, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (886, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (887, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (888, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (889, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (890, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (891, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (892, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (893, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (894, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (895, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (896, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (897, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (898, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (899, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (900, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (901, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (902, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (903, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (904, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (905, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (906, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (907, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (908, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (909, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (910, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (911, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (912, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (913, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (914, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (915, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (916, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (917, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (918, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (919, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (920, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (921, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (922, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (923, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (924, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (925, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (926, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (927, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (928, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (929, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (930, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (931, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (932, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (933, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (934, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (935, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (936, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (937, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (938, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (939, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (940, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (941, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (942, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (943, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (944, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (945, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (946, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (947, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (948, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (949, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (950, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (951, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (952, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (953, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (954, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (955, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (956, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (957, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (958, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (959, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (960, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (961, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (962, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (963, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (964, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (965, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (966, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (967, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (968, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (969, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (970, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (971, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (972, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (973, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (974, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (975, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (976, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (977, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (978, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (979, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (980, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (981, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (982, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (983, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (984, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (985, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (986, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (987, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (988, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (989, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (990, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (991, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (992, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (993, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (994, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (995, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (996, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (997, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (998, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (999, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (1000, 'Randy Random', true, '2023-03-01 00:00:00+00'); +INSERT INTO public.person VALUES (1, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (2, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (3, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (4, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (5, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (6, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (7, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (8, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (9, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (10, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (11, 'Testfried Testermann', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (12, 'Veronica Fyre', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (13, 'Miranda Rando-Generata', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (14, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (15, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (16, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (17, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (18, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (19, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (20, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (21, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (22, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (23, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (24, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (25, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (26, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (27, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (28, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (29, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (30, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (31, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (32, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (33, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (34, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (35, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (36, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (37, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (38, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (39, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (40, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (41, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (42, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (43, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (44, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (45, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (46, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (47, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (48, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (49, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (50, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (51, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (52, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (53, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (54, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (55, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (56, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (57, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (58, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (59, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (60, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (61, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (62, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (63, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (64, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (65, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (66, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (67, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (68, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (69, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (70, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (71, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (72, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (73, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (74, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (75, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (76, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (77, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (78, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (79, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (80, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (81, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (82, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (83, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (84, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (85, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (86, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (87, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (88, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (89, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (90, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (91, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (92, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (93, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (94, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (95, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (96, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (97, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (98, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (99, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (100, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (101, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (102, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (103, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (104, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (105, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (106, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (107, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (108, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (109, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (110, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (111, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (112, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (113, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (114, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (115, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (116, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (117, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (118, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (119, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (120, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (121, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (122, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (123, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (124, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (125, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (126, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (127, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (128, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (129, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (130, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (131, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (132, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (133, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (134, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (135, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (136, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (137, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (138, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (139, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (140, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (141, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (142, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (143, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (144, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (145, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (146, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (147, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (148, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (149, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (150, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (151, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (152, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (153, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (154, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (155, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (156, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (157, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (158, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (159, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (160, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (161, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (162, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (163, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (164, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (165, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (166, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (167, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (168, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (169, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (170, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (171, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (172, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (173, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (174, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (175, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (176, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (177, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (178, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (179, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (180, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (181, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (182, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (183, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (184, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (185, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (186, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (187, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (188, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (189, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (190, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (191, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (192, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (193, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (194, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (195, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (196, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (197, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (198, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (199, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (200, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (201, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (202, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (203, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (204, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (205, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (206, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (207, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (208, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (209, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (210, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (211, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (212, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (213, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (214, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (215, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (216, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (217, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (218, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (219, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (220, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (221, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (222, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (223, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (224, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (225, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (226, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (227, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (228, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (229, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (230, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (231, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (232, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (233, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (234, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (235, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (236, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (237, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (238, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (239, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (240, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (241, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (242, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (243, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (244, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (245, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (246, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (247, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (248, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (249, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (250, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (251, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (252, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (253, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (254, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (255, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (256, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (257, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (258, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (259, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (260, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (261, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (262, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (263, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (264, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (265, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (266, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (267, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (268, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (269, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (270, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (271, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (272, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (273, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (274, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (275, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (276, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (277, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (278, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (279, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (280, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (281, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (282, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (283, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (284, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (285, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (286, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (287, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (288, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (289, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (290, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (291, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (292, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (293, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (294, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (295, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (296, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (297, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (298, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (299, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (300, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (301, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (302, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (303, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (304, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (305, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (306, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (307, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (308, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (309, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (310, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (311, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (312, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (313, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (314, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (315, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (316, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (317, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (318, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (319, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (320, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (321, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (322, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (323, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (324, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (325, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (326, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (327, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (328, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (329, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (330, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (331, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (332, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (333, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (334, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (335, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (336, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (337, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (338, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (339, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (340, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (341, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (342, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (343, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (344, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (345, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (346, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (347, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (348, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (349, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (350, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (351, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (352, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (353, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (354, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (355, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (356, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (357, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (358, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (359, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (360, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (361, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (362, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (363, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (364, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (365, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (366, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (367, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (368, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (369, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (370, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (371, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (372, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (373, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (374, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (375, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (376, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (377, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (378, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (379, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (380, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (381, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (382, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (383, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (384, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (385, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (386, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (387, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (388, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (389, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (390, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (391, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (392, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (393, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (394, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (395, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (396, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (397, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (398, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (399, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (400, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (401, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (402, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (403, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (404, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (405, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (406, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (407, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (408, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (409, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (410, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (411, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (412, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (413, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (414, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (415, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (416, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (417, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (418, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (419, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (420, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (421, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (422, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (423, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (424, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (425, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (426, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (427, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (428, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (429, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (430, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (431, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (432, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (433, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (434, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (435, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (436, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (437, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (438, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (439, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (440, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (441, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (442, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (443, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (444, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (445, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (446, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (447, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (448, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (449, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (450, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (451, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (452, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (453, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (454, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (455, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (456, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (457, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (458, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (459, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (460, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (461, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (462, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (463, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (464, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (465, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (466, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (467, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (468, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (469, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (470, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (471, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (472, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (473, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (474, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (475, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (476, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (477, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (478, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (479, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (480, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (481, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (482, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (483, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (484, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (485, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (486, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (487, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (488, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (489, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (490, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (491, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (492, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (493, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (494, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (495, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (496, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (497, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (498, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (499, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (500, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (501, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (502, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (503, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (504, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (505, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (506, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (507, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (508, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (509, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (510, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (511, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (512, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (513, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (514, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (515, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (516, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (517, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (518, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (519, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (520, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (521, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (522, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (523, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (524, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (525, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (526, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (527, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (528, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (529, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (530, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (531, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (532, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (533, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (534, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (535, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (536, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (537, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (538, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (539, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (540, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (541, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (542, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (543, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (544, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (545, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (546, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (547, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (548, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (549, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (550, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (551, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (552, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (553, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (554, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (555, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (556, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (557, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (558, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (559, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (560, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (561, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (562, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (563, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (564, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (565, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (566, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (567, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (568, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (569, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (570, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (571, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (572, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (573, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (574, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (575, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (576, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (577, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (578, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (579, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (580, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (581, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (582, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (583, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (584, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (585, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (586, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (587, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (588, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (589, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (590, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (591, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (592, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (593, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (594, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (595, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (596, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (597, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (598, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (599, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (600, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (601, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (602, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (603, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (604, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (605, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (606, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (607, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (608, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (609, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (610, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (611, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (612, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (613, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (614, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (615, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (616, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (617, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (618, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (619, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (620, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (621, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (622, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (623, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (624, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (625, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (626, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (627, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (628, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (629, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (630, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (631, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (632, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (633, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (634, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (635, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (636, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (637, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (638, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (639, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (640, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (641, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (642, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (643, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (644, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (645, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (646, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (647, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (648, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (649, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (650, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (651, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (652, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (653, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (654, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (655, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (656, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (657, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (658, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (659, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (660, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (661, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (662, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (663, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (664, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (665, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (666, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (667, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (668, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (669, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (670, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (671, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (672, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (673, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (674, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (675, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (676, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (677, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (678, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (679, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (680, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (681, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (682, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (683, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (684, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (685, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (686, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (687, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (688, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (689, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (690, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (691, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (692, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (693, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (694, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (695, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (696, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (697, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (698, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (699, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (700, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (701, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (702, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (703, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (704, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (705, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (706, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (707, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (708, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (709, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (710, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (711, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (712, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (713, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (714, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (715, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (716, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (717, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (718, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (719, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (720, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (721, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (722, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (723, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (724, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (725, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (726, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (727, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (728, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (729, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (730, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (731, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (732, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (733, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (734, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (735, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (736, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (737, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (738, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (739, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (740, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (741, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (742, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (743, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (744, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (745, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (746, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (747, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (748, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (749, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (750, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (751, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (752, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (753, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (754, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (755, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (756, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (757, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (758, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (759, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (760, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (761, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (762, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (763, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (764, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (765, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (766, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (767, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (768, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (769, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (770, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (771, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (772, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (773, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (774, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (775, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (776, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (777, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (778, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (779, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (780, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (781, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (782, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (783, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (784, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (785, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (786, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (787, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (788, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (789, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (790, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (791, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (792, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (793, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (794, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (795, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (796, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (797, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (798, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (799, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (800, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (801, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (802, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (803, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (804, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (805, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (806, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (807, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (808, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (809, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (810, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (811, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (812, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (813, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (814, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (815, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (816, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (817, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (818, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (819, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (820, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (821, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (822, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (823, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (824, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (825, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (826, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (827, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (828, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (829, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (830, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (831, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (832, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (833, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (834, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (835, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (836, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (837, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (838, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (839, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (840, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (841, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (842, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (843, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (844, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (845, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (846, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (847, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (848, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (849, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (850, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (851, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (852, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (853, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (854, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (855, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (856, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (857, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (858, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (859, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (860, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (861, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (862, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (863, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (864, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (865, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (866, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (867, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (868, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (869, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (870, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (871, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (872, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (873, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (874, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (875, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (876, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (877, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (878, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (879, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (880, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (881, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (882, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (883, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (884, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (885, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (886, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (887, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (888, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (889, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (890, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (891, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (892, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (893, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (894, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (895, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (896, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (897, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (898, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (899, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (900, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (901, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (902, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (903, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (904, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (905, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (906, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (907, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (908, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (909, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (910, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (911, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (912, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (913, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (914, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (915, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (916, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (917, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (918, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (919, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (920, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (921, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (922, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (923, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (924, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (925, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (926, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (927, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (928, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (929, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (930, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (931, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (932, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (933, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (934, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (935, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (936, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (937, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (938, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (939, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (940, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (941, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (942, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (943, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (944, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (945, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (946, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (947, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (948, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (949, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (950, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (951, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (952, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (953, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (954, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (955, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (956, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (957, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (958, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (959, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (960, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (961, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (962, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (963, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (964, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (965, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (966, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (967, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (968, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (969, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (970, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (971, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (972, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (973, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (974, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (975, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (976, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (977, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (978, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (979, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (980, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (981, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (982, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (983, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (984, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (985, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (986, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (987, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (988, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (989, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (990, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (991, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (992, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (993, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (994, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (995, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (996, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (997, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (998, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (999, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (1000, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); -- diff --git a/tests/examples/src2.dump b/tests/examples/src2.dump index 409622b3..2549037d 100644 --- a/tests/examples/src2.dump +++ b/tests/examples/src2.dump @@ -184,8 +184,8 @@ ALTER TABLE public.table_to_be_ignored OWNER TO postgres; -- Data for Name: concept; Type: TABLE DATA; Schema: public; Owner: postgres -- -INSERT INTO public.concept VALUES (1, 'some concept name', 1, 'January 8 04:05:06 1999 PST'); -INSERT INTO public.concept VALUES (23, 'another concept', 2, 'January 8 04:05:06 1999 PST'); +INSERT INTO public.concept VALUES (1, 'some concept name', 1, '1999-01-08 04:05:06+00:00'); +INSERT INTO public.concept VALUES (23, 'another concept', 2, '1999-01-08 04:05:06+00:00'); -- @@ -201,11 +201,11 @@ INSERT INTO public.concept_type VALUES (3, '', 2, NULL); -- Data for Name: hospital_visit; Type: TABLE DATA; Schema: public; Owner: postgres -- -INSERT INTO public.hospital_visit VALUES (1, 99, 'January 8 04:05:06 1985 PST', 'January 10 08:07:06 1985 PST', 23); -INSERT INTO public.hospital_visit VALUES (2, 96, 'January 8 04:05:06 1990 PST', 'January 11 03:04:16 1990 PST', 23); -INSERT INTO public.hospital_visit VALUES (3, 93, 'January 8 04:05:06 1991 PST', 'January 10 12:13:14 1991 PST', 23); -INSERT INTO public.hospital_visit VALUES (4, 57, 'January 8 04:05:06 1994 PST', 'January 11 02:34:56 1994 PST', 23); -INSERT INTO public.hospital_visit VALUES (5, 17, 'January 8 04:05:06 1999 PST', 'January 10 14:15:16 1999 PST', 23); +INSERT INTO public.hospital_visit VALUES (1, 99, '1985-01-08 04:05:06+00:00', '1985-01-10 08:07:06+00:00', 23); +INSERT INTO public.hospital_visit VALUES (2, 96, '1990-01-08 04:05:06+00:00', '1990-01-11 03:04:16+00:00', 23); +INSERT INTO public.hospital_visit VALUES (3, 93, '1991-01-08 04:05:06+00:00', '1991-01-10 12:13:14+00:00', 23); +INSERT INTO public.hospital_visit VALUES (4, 57, '1994-01-08 04:05:06+00:00', '1994-01-11 02:34:56+00:00', 23); +INSERT INTO public.hospital_visit VALUES (5, 17, '1999-01-08 04:05:06+00:00', '1999-01-10 14:15:16+00:00', 23); -- @@ -226,1006 +226,1006 @@ INSERT INTO public.mitigation_type VALUES (2, 'panic', 'don''t hold back, flail -- Data for Name: person; Type: TABLE DATA; Schema: public; Owner: postgres -- -INSERT INTO public.person VALUES (1, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (2, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (3, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (4, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (5, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (6, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (7, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (8, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (9, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (10, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (11, 'Testfried Testermann', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (12, 'Veronica Fyre', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (13, 'Miranda Rando-Generata', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (14, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (15, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (16, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (17, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (18, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (19, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (20, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (21, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (22, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (23, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (24, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (25, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (26, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (27, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (28, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (29, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (30, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (31, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (32, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (33, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (34, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (35, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (36, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (37, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (38, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (39, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (40, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (41, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (42, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (43, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (44, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (45, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (46, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (47, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (48, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (49, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (50, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (51, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (52, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (53, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (54, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (55, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (56, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (57, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (58, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (59, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (60, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (61, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (62, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (63, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (64, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (65, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (66, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (67, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (68, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (69, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (70, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (71, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (72, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (73, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (74, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (75, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (76, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (77, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (78, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (79, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (80, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (81, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (82, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (83, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (84, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (85, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (86, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (87, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (88, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (89, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (90, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (91, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (92, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (93, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (94, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (95, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (96, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (97, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (98, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (99, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (100, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (101, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (102, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (103, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (104, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (105, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (106, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (107, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (108, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (109, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (110, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (111, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (112, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (113, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (114, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (115, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (116, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (117, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (118, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (119, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (120, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (121, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (122, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (123, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (124, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (125, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (126, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (127, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (128, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (129, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (130, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (131, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (132, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (133, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (134, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (135, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (136, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (137, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (138, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (139, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (140, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (141, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (142, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (143, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (144, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (145, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (146, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (147, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (148, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (149, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (150, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (151, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (152, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (153, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (154, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (155, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (156, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (157, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (158, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (159, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (160, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (161, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (162, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (163, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (164, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (165, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (166, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (167, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (168, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (169, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (170, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (171, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (172, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (173, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (174, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (175, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (176, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (177, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (178, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (179, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (180, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (181, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (182, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (183, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (184, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (185, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (186, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (187, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (188, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (189, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (190, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (191, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (192, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (193, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (194, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (195, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (196, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (197, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (198, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (199, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (200, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (201, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (202, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (203, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (204, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (205, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (206, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (207, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (208, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (209, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (210, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (211, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (212, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (213, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (214, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (215, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (216, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (217, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (218, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (219, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (220, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (221, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (222, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (223, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (224, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (225, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (226, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (227, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (228, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (229, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (230, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (231, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (232, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (233, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (234, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (235, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (236, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (237, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (238, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (239, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (240, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (241, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (242, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (243, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (244, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (245, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (246, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (247, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (248, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (249, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (250, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (251, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (252, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (253, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (254, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (255, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (256, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (257, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (258, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (259, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (260, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (261, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (262, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (263, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (264, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (265, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (266, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (267, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (268, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (269, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (270, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (271, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (272, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (273, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (274, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (275, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (276, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (277, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (278, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (279, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (280, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (281, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (282, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (283, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (284, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (285, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (286, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (287, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (288, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (289, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (290, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (291, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (292, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (293, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (294, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (295, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (296, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (297, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (298, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (299, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (300, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (301, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (302, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (303, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (304, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (305, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (306, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (307, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (308, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (309, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (310, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (311, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (312, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (313, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (314, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (315, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (316, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (317, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (318, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (319, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (320, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (321, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (322, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (323, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (324, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (325, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (326, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (327, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (328, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (329, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (330, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (331, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (332, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (333, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (334, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (335, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (336, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (337, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (338, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (339, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (340, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (341, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (342, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (343, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (344, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (345, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (346, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (347, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (348, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (349, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (350, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (351, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (352, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (353, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (354, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (355, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (356, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (357, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (358, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (359, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (360, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (361, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (362, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (363, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (364, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (365, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (366, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (367, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (368, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (369, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (370, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (371, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (372, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (373, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (374, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (375, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (376, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (377, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (378, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (379, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (380, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (381, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (382, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (383, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (384, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (385, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (386, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (387, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (388, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (389, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (390, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (391, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (392, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (393, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (394, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (395, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (396, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (397, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (398, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (399, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (400, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (401, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (402, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (403, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (404, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (405, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (406, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (407, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (408, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (409, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (410, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (411, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (412, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (413, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (414, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (415, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (416, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (417, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (418, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (419, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (420, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (421, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (422, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (423, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (424, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (425, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (426, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (427, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (428, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (429, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (430, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (431, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (432, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (433, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (434, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (435, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (436, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (437, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (438, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (439, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (440, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (441, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (442, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (443, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (444, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (445, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (446, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (447, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (448, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (449, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (450, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (451, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (452, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (453, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (454, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (455, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (456, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (457, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (458, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (459, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (460, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (461, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (462, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (463, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (464, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (465, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (466, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (467, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (468, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (469, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (470, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (471, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (472, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (473, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (474, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (475, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (476, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (477, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (478, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (479, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (480, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (481, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (482, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (483, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (484, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (485, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (486, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (487, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (488, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (489, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (490, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (491, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (492, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (493, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (494, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (495, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (496, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (497, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (498, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (499, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (500, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (501, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (502, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (503, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (504, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (505, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (506, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (507, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (508, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (509, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (510, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (511, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (512, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (513, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (514, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (515, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (516, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (517, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (518, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (519, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (520, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (521, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (522, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (523, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (524, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (525, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (526, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (527, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (528, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (529, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (530, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (531, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (532, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (533, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (534, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (535, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (536, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (537, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (538, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (539, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (540, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (541, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (542, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (543, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (544, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (545, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (546, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (547, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (548, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (549, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (550, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (551, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (552, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (553, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (554, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (555, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (556, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (557, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (558, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (559, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (560, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (561, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (562, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (563, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (564, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (565, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (566, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (567, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (568, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (569, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (570, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (571, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (572, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (573, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (574, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (575, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (576, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (577, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (578, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (579, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (580, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (581, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (582, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (583, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (584, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (585, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (586, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (587, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (588, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (589, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (590, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (591, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (592, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (593, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (594, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (595, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (596, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (597, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (598, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (599, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (600, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (601, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (602, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (603, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (604, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (605, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (606, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (607, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (608, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (609, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (610, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (611, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (612, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (613, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (614, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (615, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (616, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (617, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (618, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (619, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (620, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (621, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (622, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (623, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (624, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (625, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (626, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (627, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (628, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (629, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (630, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (631, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (632, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (633, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (634, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (635, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (636, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (637, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (638, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (639, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (640, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (641, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (642, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (643, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (644, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (645, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (646, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (647, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (648, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (649, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (650, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (651, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (652, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (653, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (654, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (655, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (656, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (657, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (658, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (659, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (660, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (661, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (662, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (663, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (664, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (665, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (666, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (667, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (668, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (669, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (670, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (671, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (672, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (673, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (674, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (675, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (676, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (677, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (678, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (679, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (680, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (681, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (682, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (683, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (684, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (685, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (686, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (687, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (688, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (689, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (690, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (691, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (692, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (693, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (694, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (695, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (696, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (697, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (698, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (699, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (700, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (701, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (702, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (703, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (704, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (705, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (706, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (707, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (708, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (709, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (710, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (711, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (712, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (713, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (714, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (715, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (716, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (717, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (718, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (719, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (720, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (721, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (722, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (723, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (724, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (725, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (726, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (727, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (728, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (729, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (730, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (731, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (732, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (733, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (734, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (735, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (736, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (737, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (738, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (739, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (740, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (741, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (742, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (743, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (744, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (745, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (746, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (747, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (748, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (749, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (750, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (751, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (752, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (753, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (754, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (755, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (756, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (757, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (758, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (759, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (760, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (761, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (762, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (763, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (764, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (765, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (766, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (767, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (768, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (769, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (770, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (771, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (772, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (773, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (774, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (775, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (776, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (777, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (778, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (779, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (780, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (781, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (782, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (783, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (784, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (785, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (786, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (787, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (788, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (789, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (790, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (791, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (792, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (793, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (794, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (795, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (796, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (797, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (798, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (799, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (800, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (801, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (802, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (803, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (804, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (805, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (806, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (807, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (808, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (809, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (810, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (811, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (812, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (813, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (814, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (815, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (816, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (817, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (818, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (819, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (820, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (821, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (822, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (823, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (824, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (825, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (826, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (827, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (828, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (829, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (830, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (831, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (832, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (833, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (834, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (835, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (836, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (837, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (838, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (839, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (840, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (841, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (842, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (843, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (844, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (845, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (846, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (847, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (848, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (849, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (850, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (851, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (852, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (853, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (854, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (855, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (856, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (857, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (858, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (859, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (860, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (861, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (862, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (863, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (864, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (865, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (866, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (867, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (868, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (869, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (870, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (871, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (872, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (873, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (874, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (875, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (876, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (877, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (878, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (879, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (880, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (881, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (882, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (883, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (884, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (885, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (886, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (887, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (888, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (889, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (890, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (891, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (892, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (893, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (894, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (895, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (896, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (897, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (898, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (899, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (900, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (901, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (902, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (903, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (904, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (905, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (906, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (907, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (908, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (909, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (910, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (911, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (912, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (913, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (914, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (915, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (916, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (917, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (918, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (919, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (920, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (921, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (922, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (923, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (924, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (925, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (926, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (927, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (928, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (929, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (930, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (931, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (932, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (933, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (934, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (935, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (936, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (937, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (938, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (939, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (940, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (941, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (942, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (943, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (944, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (945, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (946, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (947, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (948, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (949, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (950, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (951, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (952, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (953, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (954, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (955, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (956, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (957, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (958, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (959, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (960, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (961, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (962, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (963, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (964, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (965, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (966, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (967, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (968, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (969, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (970, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (971, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (972, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (973, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (974, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (975, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (976, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (977, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (978, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (979, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (980, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (981, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (982, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (983, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (984, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (985, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (986, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (987, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (988, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (989, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (990, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (991, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (992, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (993, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (994, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (995, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (996, 'Randy Random', true, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (997, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (998, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (999, 'Randy Random', false, '2023-03-01 00:00:00+00'); -INSERT INTO public.person VALUES (1000, 'Randy Random', true, '2023-03-01 00:00:00+00'); +INSERT INTO public.person VALUES (1, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (2, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (3, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (4, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (5, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (6, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (7, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (8, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (9, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (10, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (11, 'Testfried Testermann', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (12, 'Veronica Fyre', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (13, 'Miranda Rando-Generata', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (14, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (15, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (16, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (17, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (18, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (19, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (20, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (21, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (22, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (23, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (24, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (25, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (26, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (27, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (28, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (29, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (30, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (31, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (32, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (33, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (34, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (35, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (36, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (37, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (38, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (39, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (40, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (41, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (42, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (43, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (44, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (45, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (46, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (47, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (48, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (49, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (50, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (51, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (52, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (53, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (54, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (55, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (56, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (57, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (58, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (59, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (60, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (61, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (62, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (63, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (64, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (65, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (66, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (67, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (68, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (69, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (70, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (71, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (72, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (73, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (74, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (75, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (76, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (77, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (78, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (79, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (80, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (81, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (82, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (83, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (84, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (85, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (86, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (87, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (88, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (89, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (90, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (91, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (92, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (93, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (94, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (95, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (96, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (97, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (98, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (99, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (100, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (101, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (102, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (103, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (104, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (105, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (106, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (107, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (108, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (109, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (110, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (111, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (112, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (113, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (114, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (115, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (116, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (117, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (118, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (119, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (120, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (121, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (122, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (123, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (124, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (125, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (126, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (127, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (128, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (129, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (130, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (131, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (132, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (133, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (134, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (135, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (136, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (137, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (138, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (139, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (140, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (141, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (142, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (143, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (144, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (145, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (146, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (147, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (148, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (149, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (150, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (151, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (152, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (153, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (154, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (155, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (156, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (157, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (158, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (159, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (160, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (161, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (162, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (163, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (164, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (165, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (166, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (167, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (168, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (169, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (170, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (171, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (172, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (173, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (174, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (175, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (176, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (177, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (178, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (179, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (180, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (181, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (182, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (183, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (184, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (185, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (186, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (187, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (188, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (189, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (190, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (191, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (192, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (193, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (194, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (195, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (196, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (197, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (198, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (199, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (200, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (201, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (202, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (203, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (204, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (205, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (206, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (207, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (208, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (209, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (210, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (211, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (212, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (213, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (214, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (215, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (216, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (217, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (218, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (219, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (220, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (221, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (222, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (223, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (224, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (225, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (226, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (227, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (228, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (229, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (230, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (231, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (232, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (233, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (234, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (235, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (236, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (237, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (238, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (239, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (240, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (241, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (242, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (243, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (244, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (245, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (246, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (247, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (248, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (249, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (250, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (251, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (252, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (253, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (254, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (255, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (256, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (257, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (258, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (259, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (260, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (261, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (262, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (263, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (264, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (265, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (266, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (267, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (268, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (269, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (270, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (271, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (272, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (273, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (274, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (275, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (276, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (277, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (278, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (279, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (280, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (281, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (282, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (283, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (284, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (285, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (286, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (287, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (288, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (289, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (290, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (291, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (292, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (293, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (294, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (295, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (296, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (297, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (298, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (299, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (300, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (301, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (302, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (303, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (304, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (305, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (306, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (307, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (308, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (309, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (310, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (311, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (312, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (313, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (314, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (315, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (316, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (317, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (318, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (319, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (320, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (321, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (322, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (323, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (324, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (325, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (326, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (327, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (328, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (329, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (330, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (331, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (332, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (333, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (334, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (335, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (336, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (337, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (338, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (339, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (340, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (341, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (342, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (343, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (344, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (345, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (346, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (347, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (348, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (349, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (350, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (351, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (352, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (353, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (354, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (355, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (356, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (357, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (358, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (359, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (360, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (361, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (362, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (363, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (364, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (365, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (366, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (367, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (368, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (369, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (370, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (371, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (372, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (373, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (374, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (375, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (376, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (377, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (378, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (379, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (380, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (381, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (382, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (383, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (384, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (385, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (386, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (387, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (388, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (389, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (390, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (391, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (392, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (393, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (394, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (395, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (396, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (397, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (398, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (399, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (400, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (401, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (402, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (403, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (404, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (405, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (406, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (407, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (408, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (409, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (410, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (411, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (412, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (413, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (414, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (415, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (416, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (417, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (418, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (419, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (420, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (421, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (422, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (423, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (424, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (425, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (426, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (427, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (428, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (429, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (430, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (431, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (432, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (433, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (434, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (435, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (436, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (437, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (438, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (439, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (440, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (441, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (442, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (443, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (444, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (445, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (446, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (447, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (448, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (449, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (450, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (451, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (452, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (453, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (454, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (455, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (456, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (457, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (458, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (459, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (460, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (461, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (462, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (463, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (464, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (465, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (466, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (467, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (468, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (469, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (470, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (471, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (472, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (473, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (474, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (475, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (476, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (477, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (478, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (479, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (480, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (481, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (482, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (483, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (484, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (485, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (486, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (487, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (488, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (489, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (490, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (491, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (492, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (493, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (494, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (495, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (496, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (497, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (498, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (499, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (500, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (501, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (502, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (503, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (504, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (505, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (506, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (507, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (508, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (509, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (510, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (511, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (512, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (513, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (514, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (515, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (516, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (517, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (518, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (519, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (520, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (521, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (522, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (523, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (524, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (525, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (526, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (527, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (528, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (529, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (530, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (531, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (532, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (533, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (534, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (535, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (536, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (537, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (538, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (539, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (540, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (541, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (542, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (543, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (544, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (545, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (546, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (547, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (548, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (549, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (550, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (551, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (552, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (553, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (554, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (555, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (556, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (557, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (558, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (559, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (560, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (561, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (562, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (563, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (564, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (565, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (566, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (567, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (568, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (569, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (570, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (571, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (572, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (573, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (574, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (575, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (576, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (577, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (578, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (579, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (580, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (581, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (582, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (583, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (584, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (585, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (586, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (587, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (588, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (589, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (590, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (591, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (592, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (593, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (594, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (595, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (596, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (597, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (598, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (599, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (600, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (601, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (602, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (603, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (604, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (605, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (606, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (607, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (608, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (609, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (610, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (611, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (612, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (613, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (614, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (615, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (616, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (617, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (618, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (619, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (620, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (621, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (622, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (623, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (624, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (625, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (626, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (627, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (628, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (629, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (630, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (631, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (632, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (633, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (634, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (635, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (636, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (637, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (638, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (639, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (640, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (641, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (642, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (643, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (644, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (645, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (646, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (647, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (648, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (649, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (650, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (651, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (652, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (653, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (654, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (655, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (656, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (657, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (658, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (659, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (660, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (661, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (662, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (663, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (664, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (665, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (666, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (667, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (668, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (669, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (670, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (671, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (672, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (673, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (674, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (675, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (676, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (677, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (678, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (679, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (680, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (681, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (682, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (683, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (684, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (685, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (686, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (687, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (688, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (689, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (690, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (691, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (692, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (693, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (694, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (695, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (696, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (697, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (698, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (699, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (700, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (701, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (702, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (703, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (704, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (705, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (706, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (707, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (708, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (709, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (710, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (711, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (712, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (713, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (714, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (715, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (716, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (717, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (718, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (719, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (720, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (721, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (722, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (723, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (724, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (725, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (726, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (727, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (728, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (729, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (730, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (731, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (732, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (733, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (734, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (735, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (736, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (737, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (738, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (739, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (740, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (741, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (742, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (743, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (744, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (745, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (746, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (747, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (748, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (749, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (750, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (751, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (752, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (753, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (754, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (755, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (756, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (757, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (758, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (759, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (760, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (761, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (762, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (763, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (764, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (765, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (766, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (767, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (768, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (769, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (770, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (771, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (772, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (773, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (774, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (775, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (776, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (777, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (778, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (779, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (780, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (781, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (782, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (783, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (784, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (785, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (786, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (787, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (788, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (789, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (790, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (791, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (792, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (793, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (794, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (795, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (796, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (797, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (798, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (799, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (800, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (801, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (802, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (803, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (804, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (805, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (806, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (807, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (808, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (809, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (810, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (811, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (812, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (813, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (814, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (815, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (816, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (817, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (818, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (819, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (820, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (821, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (822, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (823, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (824, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (825, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (826, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (827, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (828, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (829, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (830, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (831, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (832, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (833, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (834, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (835, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (836, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (837, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (838, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (839, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (840, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (841, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (842, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (843, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (844, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (845, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (846, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (847, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (848, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (849, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (850, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (851, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (852, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (853, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (854, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (855, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (856, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (857, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (858, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (859, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (860, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (861, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (862, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (863, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (864, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (865, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (866, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (867, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (868, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (869, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (870, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (871, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (872, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (873, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (874, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (875, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (876, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (877, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (878, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (879, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (880, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (881, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (882, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (883, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (884, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (885, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (886, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (887, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (888, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (889, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (890, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (891, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (892, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (893, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (894, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (895, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (896, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (897, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (898, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (899, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (900, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (901, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (902, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (903, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (904, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (905, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (906, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (907, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (908, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (909, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (910, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (911, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (912, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (913, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (914, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (915, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (916, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (917, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (918, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (919, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (920, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (921, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (922, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (923, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (924, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (925, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (926, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (927, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (928, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (929, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (930, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (931, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (932, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (933, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (934, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (935, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (936, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (937, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (938, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (939, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (940, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (941, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (942, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (943, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (944, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (945, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (946, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (947, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (948, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (949, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (950, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (951, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (952, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (953, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (954, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (955, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (956, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (957, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (958, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (959, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (960, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (961, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (962, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (963, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (964, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (965, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (966, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (967, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (968, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (969, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (970, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (971, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (972, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (973, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (974, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (975, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (976, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (977, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (978, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (979, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (980, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (981, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (982, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (983, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (984, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (985, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (986, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (987, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (988, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (989, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (990, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (991, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (992, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (993, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (994, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (995, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (996, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (997, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (998, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (999, 'Someone Random', false, '2023-03-01 00:00:00+00:00'); +INSERT INTO public.person VALUES (1000, 'Someone Random', true, '2023-03-01 00:00:00+00:00'); -- diff --git a/tests/test_create.py b/tests/test_create.py index 2a4eeed4..63cef5fa 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -31,7 +31,12 @@ from datafaker.populate import TableGenerator from datafaker.serialize_metadata import dict_to_metadata, metadata_to_dict from datafaker.settings import SettingsError -from tests.utils import DatafakerTestCase, GeneratesDBTestCase, RequiresDBTestCase +from tests.utils import ( + DatafakerTestCase, + GeneratesDBTestCase, + MsSqlTestDb, + RequiresDBTestCase, +) class TestCreate(GeneratesDBTestCase): @@ -179,7 +184,7 @@ def story() -> Generator[Tuple[str, dict], None, None]: mock_metadata = MagicMock(spec=MetaData) mock_gen = MagicMock(spec=TableGenerator) mock_gen.num_rows_per_pass = num_rows_per_pass - mock_gen.return_value = {} + mock_gen.generate_row.return_value = {} row_counts = Counter( {table_name: num_initial_rows} if num_initial_rows > 0 else {} ) @@ -215,7 +220,7 @@ def story() -> Generator[Tuple[str, dict], None, None]: row_counts, ) self.assertListEqual( - [call(mock_gen.return_value)] + [call(mock_gen.generate_row.return_value)] * (num_stories_per_pass + num_rows_per_pass), mock_values.call_args_list, ) @@ -245,8 +250,8 @@ def test_populate_diff_length(self, mock_insert: MagicMock) -> None: [call(mock_table_two), call(mock_table_three)], mock_insert.call_args_list ) - mock_gen_two.assert_called_once() - mock_gen_three.assert_called_once() + mock_gen_two.generate_row.assert_called_once() + mock_gen_three.generate_row.assert_called_once() class MockFunctionUsingConnection: @@ -405,6 +410,7 @@ class CreateDataTestCase(RequiresDBTestCase): dump_file_path = "empty.sql" database_name = "empty" schema_name = "public" + dst_schema_name = "fake" def test_create_data_minimal(self) -> None: """Test creating one table with one PK column.""" @@ -518,3 +524,10 @@ def test_story_incorrect_name_minimal(self) -> None: self.schema_name, metadata, ) + + +class CreateDataTestCaseMsSql(CreateDataTestCase): + """CreateData but for MSSQL.""" + + database_type = MsSqlTestDb + schema_name = None diff --git a/tests/test_create_mssql.py b/tests/test_create_mssql.py new file mode 100644 index 00000000..f5e7d815 --- /dev/null +++ b/tests/test_create_mssql.py @@ -0,0 +1,87 @@ +"""Tests for MS-SQL DDL compilation in datafaker.create.""" +import unittest + +from sqlalchemy import Column, ForeignKey, Integer, MetaData, Table +from sqlalchemy.dialects import mssql +from sqlalchemy.schema import CreateTable + + +def _compile_create_table(table: Table) -> str: + """Compile a CreateTable statement against the MS-SQL dialect.""" + return str( + CreateTable(table).compile( + dialect=mssql.dialect(), compile_kwargs={"literal_binds": True} + ) + ) + + +class TestMSSQLIdentityAbsent(unittest.TestCase): + """MS-SQL tables must NOT have IDENTITY — datafaker supplies explicit PK values. + + The remove_mssql_identity hook strips IDENTITY from CREATE TABLE DDL so that + ColumnValueProvider.increment() can insert explicit PK values without needing + SET IDENTITY_INSERT ON. + """ + + def _make_table(self) -> Table: + meta = MetaData() + return Table( + "test_table", + meta, + Column("id", Integer(), primary_key=True, autoincrement=True), + Column("value", Integer(), nullable=True), + ) + + def test_identity_absent_from_ddl(self) -> None: + """IDENTITY must be stripped so datafaker can insert explicit PK values.""" + ddl = _compile_create_table(self._make_table()) + self.assertNotIn("IDENTITY", ddl) + + def test_integer_type_preserved(self) -> None: + """The INTEGER type is preserved.""" + ddl = _compile_create_table(self._make_table()) + self.assertIn("INTEGER", ddl) + + def test_primary_key_constraint_preserved(self) -> None: + """PRIMARY KEY constraint is not affected.""" + ddl = _compile_create_table(self._make_table()) + self.assertIn("PRIMARY KEY", ddl) + + def test_non_autoincrement_column_unchanged(self) -> None: + """Non-autoincrement columns are not altered.""" + ddl = _compile_create_table(self._make_table()) + self.assertIn("value", ddl.lower()) + + +class TestMSSQLRemoveOnDeleteCascade(unittest.TestCase): + """@compiles(CreateTable, 'mssql') strips ON DELETE CASCADE to avoid error 1785.""" + + def _make_multi_fk_table(self) -> Table: + meta = MetaData() + concept_id = Column("concept_id", Integer()) + Table("concept", meta, concept_id) + return Table( + "person", + meta, + Column("person_id", Integer(), primary_key=True), + Column( + "gender_concept_id", + Integer(), + ForeignKey(concept_id, ondelete="CASCADE"), + ), + Column( + "race_concept_id", + Integer(), + ForeignKey(concept_id, ondelete="CASCADE"), + ), + ) + + def test_cascade_absent_from_mssql_ddl(self) -> None: + """Test that CASCADE does not appear in the CREATE TABLE statement.""" + ddl = _compile_create_table(self._make_multi_fk_table()) + self.assertNotIn("ON DELETE CASCADE", ddl) + + def test_foreign_key_constraint_preserved(self) -> None: + """Test that a foreign key appears in the CREATE TABLE statement.""" + ddl = _compile_create_table(self._make_multi_fk_table()) + self.assertIn("FOREIGN KEY", ddl) diff --git a/tests/test_dump.py b/tests/test_dump.py index b16673ca..8237152f 100644 --- a/tests/test_dump.py +++ b/tests/test_dump.py @@ -11,7 +11,7 @@ from datafaker.dump import CsvTableWriter, get_parquet_table_writer from datafaker.main import app -from tests.utils import DatafakerTestCase, RequiresDBTestCase, TestDuckDb +from tests.utils import DatafakerTestCase, DuckTestDb, MsSqlTestDb, RequiresDBTestCase class DumpTests(RequiresDBTestCase): @@ -52,12 +52,14 @@ def test_dump_data_csv(self) -> None: reader = csv.reader(table_fh) content = list(reader) self.assertListEqual(content[0], ["id", "name", "founded"]) - self.assertListEqual( - content[1], ["1", "Blender", "1951-01-08 12:05:06+00:00"] - ) - self.assertListEqual( - content[2], ["2", "Gibbs", "1959-03-04 15:08:09+00:00"] - ) + self.assertEqual(len(content[1]), 3) + self.assertEqual(content[1][0], "1") + self.assertEqual(content[1][1], "Blender") + self.assertRegex(content[1][2], r"1951\-01\-08 12:05:06(\+00:00)?") + self.assertEqual(len(content[2]), 3) + self.assertEqual(content[2][0], "2") + self.assertEqual(content[2][1], "Gibbs") + self.assertRegex(content[2][2], r"1959\-03\-04 15:08:09(\+00:00)?") def test_dump_data_parquet(self) -> None: """Test dump-data for Parquet output.""" @@ -85,13 +87,20 @@ def test_dump_data_parquet(self) -> None: class DumpTestsDuckDb(DumpTests): """DumpTests against DuckDB.""" - database_type = TestDuckDb + database_type = DuckTestDb + + +class DumpTestsMsSql(DumpTests): + """DumpTests against MS Sql.""" + + database_type = MsSqlTestDb + schema_name = None class EndToEndParquetTestCase(DatafakerTestCase): """Read in parquet, make some generators, output parquet.""" - database_type = TestDuckDb + database_type = DuckTestDb examples_dir = Path("examples/duckdb") def set_working_dir(self) -> None: diff --git a/tests/test_functional.py b/tests/test_functional.py index ca5680ae..c0cd7d51 100644 --- a/tests/test_functional.py +++ b/tests/test_functional.py @@ -10,7 +10,7 @@ from typer.testing import CliRunner, Result from datafaker.main import app -from tests.utils import RequiresDBTestCase, TestDuckDb +from tests.utils import DuckTestDb, MsSqlTestDb, RequiresDBTestCase # pylint: disable=subprocess-run-check @@ -33,13 +33,12 @@ class DBFunctionalTestCaseBase(RequiresDBTestCase): def setUp(self) -> None: """Pre-test setup.""" super().setUp() - dst_name = "dst" - self.make_destination_database(dst_name) + self.make_destination_database("dst") self.env = { "src_dsn": self.dsn, "src_schema": self.schema_name, "dst_dsn": self.dst_dsn, - "dst_schema": "dstschema", + "dst_schema": self.dst_schema_name, } self.runner = CliRunner( mix_stderr=False, @@ -98,7 +97,6 @@ class DBFunctionalTestCasePg(DBFunctionalTestCaseBase): dump_file_path = "src.dump" database_name = "src" - schema_name = "public" alt_orm_file_path = Path("my_orm.yaml") config_file_path = Path("example_config.yaml") @@ -581,4 +579,11 @@ def test_row_hyphens_in_name(self) -> None: class DuckDbFunctionalTestCase(DBFunctionalTestCase): """End-to-end tests for the DuckDB workflow.""" - database_type = TestDuckDb + database_type = DuckTestDb + + +class MsSqlFunctionalTestCase(DBFunctionalTestCase): + """End-to-end tests for the MsSql workflow.""" + + schema_name = None + database_type = MsSqlTestDb diff --git a/tests/test_functional_mssql.py b/tests/test_functional_mssql.py new file mode 100644 index 00000000..dbd6415f --- /dev/null +++ b/tests/test_functional_mssql.py @@ -0,0 +1,143 @@ +"""End-to-end tests for the MS-SQL Server dialect. + +These tests require a running SQL Server instance. Set the ``MSSQL_TEST_DSN`` +environment variable to a ``mssql+pyodbc://`` connection string to enable them: + + export MSSQL_TEST_DSN="mssql+pyodbc://sa:Datafaker!Test123@\ + localhost:1433/master?driver=ODBC+Driver+18+for+SQL+Server\ + &TrustServerCertificate=yes" + +With docker-compose: + + docker compose up -d mssql + # wait ~30 s for SQL Server to start +""" +import asyncio +import os +from tempfile import mkstemp + +import yaml +from sqlalchemy import create_engine as sa_create_engine +from sqlalchemy import text +from sqlalchemy.dialects import mssql as mssql_dialect # noqa: PLC0415 +from sqlalchemy.schema import CreateTable + +from datafaker.make import make_src_stats, make_tables_file +from datafaker.proposers.choice import ZipfChoiceProposer # noqa: PLC0415 +from tests.utils import DatafakerTestCase, GeneratesDBTestCase, MsSqlTestDb + +_EXPECTED_TABLES = frozenset( + {"manufacturer", "model", "string", "player", "signature_model"} +) + + +# --------------------------------------------------------------------------- +# Test case +# --------------------------------------------------------------------------- + + +class MSSQLFunctionalTestCase(GeneratesDBTestCase): + """End-to-end tests exercising the full datafaker pipeline against SQL Server.""" + + database_type = MsSqlTestDb + dump_file_path = "instrument.sql" + database_name = "instrument" + schema_name = None + dst_schema_name = "dst" + + def setUp(self) -> None: + super().setUp() + + # Write orm.yaml so generate_data() has the file it expects. + (self.orm_fd, self.orm_file_path) = mkstemp(".yaml", "orm_", text=True) + with os.fdopen(self.orm_fd, "w", encoding="utf-8") as fh: + fh.write( + make_tables_file(self.dsn, self.schema_name, engine=self.sync_engine) + ) + + def tearDown(self) -> None: + # Dispose connection pools so the next setUp can drop these databases. + if hasattr(self, "sync_engine"): + self.sync_engine.dispose() + if hasattr(self, "dst_engine") and self.dst_engine is not None: + self.dst_engine.dispose() + if self.database is not None: + self.database.close() + if self.dst_database is not None: + self.dst_database.close() + DatafakerTestCase.tearDown(self) + + # ------------------------------------------------------------------ + # Tests + # ------------------------------------------------------------------ + + def test_smoke_connect(self) -> None: + """ODBC driver can connect and run a trivial query.""" + engine = sa_create_engine(self.dsn) + with engine.connect() as conn: + row = conn.execute(text("SELECT 1 AS n")).fetchone() + assert row is not None + self.assertEqual(row[0], 1) + + def test_make_tables(self) -> None: + """make_tables_file produces an orm.yaml listing the expected tables.""" + # setUp already called make_tables_file and wrote the result to orm_file_path + with open(self.orm_file_path, encoding="utf-8") as fh: + orm = yaml.safe_load(fh) + # orm["tables"] is a dict keyed by table name + table_names = set(orm.get("tables", {}).keys()) + self.assert_subset(_EXPECTED_TABLES, table_names) + + def test_make_stats(self) -> None: + """make_src_stats runs without error against SQL Server. + + With an empty config there are no src-stats query blocks to run, so the + function returns an empty dict — that is the correct behaviour. + """ + loop = asyncio.new_event_loop() + try: + src_stats = loop.run_until_complete( + make_src_stats(self.dsn, {}, self.schema_name) + ) + finally: + loop.close() + self.assertIsInstance(src_stats, dict) + + def test_create_data(self) -> None: + """Full pipeline: make-stats → create-tables → create-data inserts rows.""" + self.generate_data({}) + + # Verify that at least the manufacturer table received rows. + assert self.dst_engine is not None + with self.dst_engine.connect() as conn: + count = conn.execute( + text(f"SELECT COUNT(*) FROM {self.dst_schema_name}.manufacturer") + ).scalar() + self.assertGreater(count, 0, "Expected rows in manufacturer after create-data") + + def test_dialect_rand(self) -> None: + """ChoiceProposer compiles its query with NEWID() not RANDOM() for mssql.""" + + dialect = mssql_dialect.dialect() + proposer = ZipfChoiceProposer( + table_name="manufacturer", + column_name="name", + values=["Blender", "Gibbs"], + counts=[5, 5], + sample_count=2, + dialect=dialect, + ) + self.assertIn("newid()", proposer._query.lower()) # pylint: disable=W0212 + self.assertNotIn("random()", proposer._query.lower()) # pylint: disable=W0212 + + def test_cascade_stripped(self) -> None: + """The @compiles(CreateTable, 'mssql') hook strips ON DELETE CASCADE.""" + + model_table = self.metadata.tables["model"] + ddl = str( + CreateTable(model_table).compile( + dialect=mssql_dialect.dialect(), compile_kwargs={"literal_binds": True} + ) + ) + self.assertIn("FOREIGN KEY", ddl) + self.assertNotIn("ON DELETE CASCADE", ddl) diff --git a/tests/test_generators_dialect.py b/tests/test_generators_dialect.py new file mode 100644 index 00000000..69a81fc0 --- /dev/null +++ b/tests/test_generators_dialect.py @@ -0,0 +1,666 @@ +"""Tests for dialect-correct SQL in generator classes.""" +# pylint: disable=protected-access +import unittest +import unittest.mock +from unittest.mock import MagicMock + +from sqlalchemy import Column, Integer, MetaData, Select, Table, literal_column +from sqlalchemy.dialects import mssql, postgresql +from sqlalchemy.types import DateTime + +from datafaker.dialects import SecondsDifference +from datafaker.interactive.generators import get_aggregate_query +from datafaker.interactive.missingness import MissingnessType +from datafaker.proposers.base import Buckets, PredefinedProposer, Proposer +from datafaker.proposers.choice import ChoiceProposerFactory, ZipfChoiceProposer +from datafaker.proposers.continuous import ( + ContinuousLogDistributionProposerFactory, + CovariateQuery, + GaussianProposer, + LogNormalProposer, +) +from datafaker.proposers.intervals import DateAfterProposer +from datafaker.proposers.mimesis import MimesisDateTimeProposer +from tests.utils import DatafakerTestCase + + +class TestMimesisDateTimeDialect(DatafakerTestCase): + """MimesisDateTimeGenerator.make_singleton compiles year expressions per dialect.""" + + def _make_column(self) -> Column: + meta = MetaData() + t = Table("person", meta, Column("birth_datetime", DateTime())) + return t.c.birth_datetime + + def _make_engine(self, dialect) -> MagicMock: + engine = MagicMock() + engine.dialect = dialect() + result = MagicMock() + result.start = 1950 + result.end = 2000 + conn = MagicMock() + conn.__enter__ = MagicMock(return_value=conn) + conn.__exit__ = MagicMock(return_value=False) + conn.execute.return_value.first.return_value = result + engine.connect.return_value = conn + return engine + + def test_postgresql_uses_extract(self) -> None: + """PostgreSQL year clause uses EXTRACT.""" + + column = self._make_column() + engine = self._make_engine(postgresql.dialect) + gens = MimesisDateTimeProposer.make_singleton( + column, engine, "datetime.datetime" + ) + self.assertEqual(len(gens), 1) + clauses = gens[0].select_aggregate_clauses() + min_clause = clauses["birth_datetime__start"]["clause"] + max_clause = clauses["birth_datetime__end"]["clause"] + self.assert_str_in("EXTRACT", min_clause.upper()) + self.assert_str_in("EXTRACT", max_clause.upper()) + self.assert_str_not_in("DATEPART", min_clause.upper()) + + def test_mssql_uses_datepart(self) -> None: + """MS-SQL year clause uses DATEPART.""" + + column = self._make_column() + engine = self._make_engine(mssql.dialect) + gens = MimesisDateTimeProposer.make_singleton( + column, engine, "datetime.datetime" + ) + self.assertEqual(len(gens), 1) + clauses = gens[0].select_aggregate_clauses() + min_clause = clauses["birth_datetime__start"]["clause"] + max_clause = clauses["birth_datetime__end"]["clause"] + self.assert_str_in("DATEPART", min_clause.upper()) + self.assert_str_in("DATEPART", max_clause.upper()) + self.assert_str_not_in("EXTRACT", min_clause.upper()) + + +class TestBucketsStddevDialect(DatafakerTestCase): + """Buckets.make_buckets uses STDEV on MS-SQL and STDDEV on other dialects.""" + + def _make_engine_with_dialect_name(self, dialect_name: str) -> MagicMock: + engine = MagicMock() + engine.dialect.name = dialect_name + result = MagicMock() + result.stddev = 5.0 + result.mean = 42.0 + # count attribute via getattr + result.configure_mock(**{"count": 100}) + conn = MagicMock() + conn.__enter__ = MagicMock(return_value=conn) + conn.__exit__ = MagicMock(return_value=False) + conn.execute.return_value.first.return_value = result + engine.connect.return_value = conn + return engine + + def _get_executed_sql(self, dialect_name: str) -> str: + engine = self._make_engine_with_dialect_name(dialect_name) + # make_buckets will call engine.connect().execute(stmt) + # We patch it to capture the compiled SQL + executed_stmts = [] + orig_execute = engine.connect.return_value.execute + + def capture_execute(stmt, *args, **kwargs): + executed_stmts.append(stmt) + return orig_execute(stmt, *args, **kwargs) + + engine.connect.return_value.execute = capture_execute + # Prevent the Buckets constructor from running (it uses a separate query) + tbl = Table("person", MetaData(), Column("age", Integer())) + with unittest.mock.patch.object(Buckets, "__init__", return_value=None): + Buckets.make_buckets(engine, tbl, tbl.c.age) + + self.assertEqual(len(executed_stmts), 1) + compiled = str( + executed_stmts[0].compile( + dialect=mssql.dialect() + if dialect_name == "mssql" + else postgresql.dialect(), + compile_kwargs={"literal_binds": True}, + ) + ) + return compiled.upper() + + def test_postgresql_uses_stddev(self) -> None: + """PostgreSQL query uses STDDEV function.""" + + sql = self._get_executed_sql("postgresql") + self.assert_str_in("STDDEV(", sql) # function call form + + def test_mssql_uses_stdev(self) -> None: + """MS-SQL query uses STDEV function (no trailing D).""" + sql = self._get_executed_sql("mssql") + self.assert_str_in("STDEVP(", sql) + self.assert_str_not_in("STDDEV(", sql) # function call form only, not the alias + + +class TestChoiceGeneratorStoredQuery(DatafakerTestCase): + """ChoiceGenerator._query is compiled to dialect-correct SQL at construction time.""" + + def _make_gen(self, dialect, sample_count=None, suppress_count=0): + return ZipfChoiceProposer( + table_name="patient", + column_name="gender", + values=["M", "F"], + counts=[70, 30], + sample_count=sample_count, + suppress_count=suppress_count, + dialect=dialect, + ) + + def test_postgresql_sample_uses_random_and_limit(self) -> None: + """PostgreSQL stored query uses random() and LIMIT for sampled path.""" + gen = self._make_gen(postgresql.dialect(), sample_count=500) + sql = gen._query.upper() + self.assert_str_in("RANDOM()", sql) + self.assert_str_in("LIMIT", sql) + self.assert_str_not_in("NEWID()", sql) + self.assert_str_not_in("RAND()", sql) + self.assert_str_not_in(" TOP ", sql) + self.assert_str_not_in("ROW_NUMBER()", sql) + + def test_mssql_sample_uses_rand_and_top(self) -> None: + """MS-SQL stored query uses newid() and TOP for sampled path.""" + gen = self._make_gen(mssql.dialect(), sample_count=500) + sql = gen._query.upper() + self.assert_str_in("NEWID()", sql) + self.assert_str_in(" TOP ", sql) + self.assert_str_not_in("RANDOM()", sql) + self.assert_str_not_in("LIMIT", sql) + + def test_mssql_suppress_has_no_order_by(self) -> None: + """MS-SQL suppress-only path emits no ORDER BY (was rejected without TOP).""" + gen = self._make_gen(mssql.dialect(), suppress_count=7) + sql = gen._query.upper() + self.assert_str_not_in("ORDER BY", sql) + + def test_mssql_sample_and_suppress_uses_rand_and_top(self) -> None: + """MS-SQL sample+suppress path uses newid()/TOP and no LIMIT/RANDOM.""" + gen = self._make_gen(mssql.dialect(), sample_count=500, suppress_count=7) + sql = gen._query.upper() + self.assert_str_in("NEWID()", sql) + self.assert_str_in(" TOP ", sql) + self.assert_str_not_in("RANDOM()", sql) + self.assert_str_not_in("LIMIT", sql) + + def test_no_sample_no_suppress_has_no_random_or_limit(self) -> None: + """No-sample path never includes RANDOM/LIMIT regardless of dialect.""" + for dialect in (postgresql.dialect(), mssql.dialect()): + with self.subTest(dialect=dialect.name): + gen = self._make_gen(dialect) + sql = gen._query.upper() + self.assert_str_not_in("RANDOM()", sql) + self.assert_str_not_in("RAND()", sql) + self.assert_str_not_in("NEWID()", sql) + self.assert_str_not_in("LIMIT", sql) + self.assert_str_not_in(" TOP ", sql) + self.assert_str_not_in("ROW_NUMBER()", sql) + + +class TestChoiceGeneratorFactoryLiveQueries(DatafakerTestCase): + """ChoiceGeneratorFactory.get_generators executes dialect-correct live SQL.""" + + def _captured_sqls(self, dialect, schema=None) -> list[str]: + """Run get_proposers with a mocked engine and return compiled SQL strings.""" + + engine = MagicMock() + engine.dialect = dialect + + row_count = MagicMock() + row_count.v = "M" + row_count.f = 70 + result_count = MagicMock() + result_count.rowcount = 1 + result_count.__iter__ = MagicMock(return_value=iter([row_count])) + + row_sample = MagicMock() + row_sample.v = "M" + row_sample.f = 70 + result_sample = MagicMock() + result_sample.__iter__ = MagicMock(return_value=iter([row_sample])) + + conn = MagicMock() + conn.__enter__ = MagicMock(return_value=conn) + conn.__exit__ = MagicMock(return_value=False) + engine.connect.return_value = conn + + executed = [] + results_queue = [result_count, result_sample] + + def capture(stmt, *_args, **_kwargs): + executed.append(stmt) + return results_queue[len(executed) - 1] + + conn.execute.side_effect = capture + + meta = MetaData() + tbl = Table("patient", meta, Column("gender", Integer()), schema=schema) + ChoiceProposerFactory().get_proposers([tbl.c.gender], engine) + + return [ + str( + s.compile(dialect=dialect, compile_kwargs={"literal_binds": True}) + ).upper() + for s in executed + ] + + def test_mssql_live_queries_use_rand_and_top(self) -> None: + """MS-SQL live queries use TOP (not LIMIT) and rand() (not random()).""" + sqls = self._captured_sqls(mssql.dialect()) + self.assert_str_in(" TOP ", sqls[0]) + self.assert_str_not_in("LIMIT", sqls[0]) + self.assert_str_in("NEWID()", sqls[1]) + self.assert_str_not_in("LIMIT", sqls[1]) + self.assert_str_not_in("RANDOM()", sqls[1]) + + def test_postgresql_live_queries_use_limit_and_random(self) -> None: + """PostgreSQL live queries use LIMIT and random().""" + sqls = self._captured_sqls(postgresql.dialect()) + self.assert_str_in("LIMIT", sqls[0]) + self.assert_str_not_in(" TOP ", sqls[0]) + self.assert_str_in("LIMIT", sqls[1]) + self.assert_str_in("RANDOM()", sqls[1]) + self.assert_str_not_in(" TOP ", sqls[1]) + self.assert_str_not_in("NEWID()", sqls[1]) + + def test_schema_qualified_table_appears_in_from(self) -> None: + """Schema-qualified table name is included in the FROM clause on both dialects.""" + for dialect in (mssql.dialect(), postgresql.dialect()): + with self.subTest(dialect=dialect.name): + sqls = self._captured_sqls(dialect, schema="myschema") + for sql in sqls: + self.assert_str_in("MYSCHEMA", sql) + + +class TestBucketsSchemaQualified(DatafakerTestCase): + """Buckets.make_buckets respects the schema of the src_table argument.""" + + def _make_engine(self, dialect_name: str) -> MagicMock: + engine = MagicMock() + engine.dialect.name = dialect_name + result = MagicMock() + result.stddev = 5.0 + result.mean = 42.0 + result.configure_mock(**{"count": 100}) + conn = MagicMock() + conn.__enter__ = MagicMock(return_value=conn) + conn.__exit__ = MagicMock(return_value=False) + conn.execute.return_value.first.return_value = result + conn.execute.return_value.__iter__ = MagicMock(return_value=iter([])) + engine.connect.return_value = conn + return engine + + def _get_make_buckets_sql(self, dialect_name: str, schema: str | None) -> str: + engine = self._make_engine(dialect_name) + meta = MetaData() + tbl = Table("person", meta, Column("age", Integer()), schema=schema) + + executed_stmts = [] + orig_execute = engine.connect.return_value.execute + + def capture_execute(stmt, *args, **kwargs): + executed_stmts.append(stmt) + return orig_execute(stmt, *args, **kwargs) + + engine.connect.return_value.execute = capture_execute + + with unittest.mock.patch.object(Buckets, "__init__", return_value=None): + Buckets.make_buckets(engine, tbl, tbl.c.age) + + self.assertGreaterEqual(len(executed_stmts), 1) + dialect = mssql.dialect() if dialect_name == "mssql" else postgresql.dialect() + return str( + executed_stmts[0].compile( + dialect=dialect, + compile_kwargs={"literal_binds": True}, + ) + ).upper() + + def test_schema_appears_in_from_mssql(self) -> None: + """MS-SQL make_buckets query includes schema in FROM clause.""" + sql = self._get_make_buckets_sql("mssql", schema="myschema") + self.assert_str_in("MYSCHEMA", sql) + + def test_schema_appears_in_from_postgresql(self) -> None: + """PostgreSQL make_buckets query includes schema in FROM clause.""" + sql = self._get_make_buckets_sql("postgresql", schema="myschema") + self.assert_str_in("MYSCHEMA", sql) + + def test_no_schema_omits_qualifier(self) -> None: + """Without schema, FROM clause has no schema.table qualifier.""" + sql = self._get_make_buckets_sql("postgresql", schema=None) + # A schema qualifier would appear as "SCHEMA.PERSON"; no dot before the table name. + self.assert_str_not_in(".PERSON", sql) + + +class TestCovariateQueryDialect(DatafakerTestCase): + """CovariateQuery._inner_query() uses TOP/NEWID on MS-SQL and RANDOM/LIMIT elsewhere.""" + + def _make_factory(self) -> MagicMock: + factory = MagicMock() + factory.query_predicate.return_value = "" + return factory + + def _inner_query(self) -> Select: + metadata = MetaData() + cq = CovariateQuery( + Table("person", metadata, Column("name")), + self._make_factory(), + ).sample_count(500) + return cq._inner_query() + + +class TestMissingnessQueryDialect(DatafakerTestCase): + """MissingnessType.sampled_query() produces dialect-correct SQL.""" + + def setUp(self): + super().setUp() + self.metadata = MetaData() + self.col_a = Column("col_a") + self.col_b = Column("col_b") + self.table = Table("person", self.metadata, self.col_a, self.col_b) + + def test_mssql_uses_rand_and_rownumber(self) -> None: + """ + Test that MSSQL uses RAND and ROW_NUMBER for sampling. + + SELECT … ROW_NUMBER() AS MSSQL_RN + WHERE MSSQL_RN < n ORDER BY NEWID(). + """ + + sql = MissingnessType.sampled_query( + self.table, 1000, [self.col_a, self.col_b], dialect=mssql.dialect() + ).upper() + self.assert_str_in("ROW_NUMBER()", sql) + self.assert_str_in("<= 1000", sql) + self.assert_str_in("NEWID()", sql) + self.assert_str_not_in("RANDOM()", sql) + self.assert_str_not_in("LIMIT", sql) + + def test_default_uses_random_and_limit(self) -> None: + """Default (no dialect) sampled query uses RANDOM() and LIMIT.""" + + sql = MissingnessType.sampled_query( + self.table, 1000, [self.col_a], dialect=postgresql.dialect() + ).upper() + self.assert_str_in("RANDOM()", sql) + self.assert_str_in("LIMIT 1000", sql) + self.assert_str_not_in("RAND()", sql) + self.assert_str_not_in("NEWID()", sql) + self.assert_str_not_in("TOP", sql) + self.assert_str_not_in("ROW_NUMBER()", sql) + + def test_mssql_result_contains_column_null_checks(self) -> None: + """MS-SQL sampled query retains IS NULL expressions for the named columns.""" + + sql = MissingnessType.sampled_query( + self.table, 500, [self.col_a], dialect=mssql.dialect() + ) + self.assert_str_in("col_a IS NULL", sql) + self.assert_str_in("col_a__is_null", sql) + + +class TestLogNormalGeneratorSchemaQualified(DatafakerTestCase): + """ContinuousLogDistributionGeneratorFactory respects src_table schema.""" + + def _get_sql(self, schema: str | None) -> str: + meta = MetaData() + tbl = Table("person", meta, Column("age", Integer()), schema=schema) + + executed_stmts = [] + result = MagicMock() + result.logmean = 1.0 + result.logstddev = 0.5 + conn = MagicMock() + conn.__enter__ = MagicMock(return_value=conn) + conn.__exit__ = MagicMock(return_value=False) + orig_execute = MagicMock( + return_value=MagicMock(first=MagicMock(return_value=result)) + ) + + def capture(stmt, *args, **kwargs): + executed_stmts.append(stmt) + return orig_execute(stmt, *args, **kwargs) + + conn.execute.side_effect = capture + engine = MagicMock() + engine.connect.return_value = conn + + buckets = MagicMock(spec=Buckets) + factory = ContinuousLogDistributionProposerFactory() + with unittest.mock.patch.object(Buckets, "make_buckets", return_value=buckets): + factory._get_generators_from_buckets(engine, tbl, tbl.c["age"], buckets) + + self.assertEqual(len(executed_stmts), 1) + dialect = postgresql.dialect() + return str( + executed_stmts[0].compile( + dialect=dialect, + compile_kwargs={"literal_binds": True}, + ) + ).upper() + + def test_schema_appears_in_from(self) -> None: + """_get_generators_from_buckets includes schema in FROM clause.""" + sql = self._get_sql(schema="myschema") + self.assert_str_in("MYSCHEMA", sql) + + def test_no_schema_omits_qualifier(self) -> None: + """Without schema, FROM clause has no schema prefix.""" + sql = self._get_sql(schema=None) + self.assert_str_in("FROM PERSON", sql) + self.assert_str_not_in("FROM MYSCHEMA", sql) + + +class TestPredefinedGeneratorSchemaQualified(DatafakerTestCase): + """PredefinedGenerator parses aggregate clauses from schema-qualified SQL.""" + + def _make_config(self, table_sql_name: str) -> dict: + return { + "tables": { + "person": { + "row_generators": [ + { + "name": "dist_gen.gaussian", + "columns_assigned": ["age"], + "kwargs": { + "mean": 'SRC_STATS["auto__person"]["results"][0]["mean__age"]', + "sd": 'SRC_STATS["auto__person"]["results"][0]["sd__age"]', + }, + } + ] + } + }, + "src-stats": [ + { + "name": "auto__person", + "query": ( + "SELECT AVG(age) AS mean__age," + + " STDDEV(age) AS sd__age FROM " + + table_sql_name + ), + "comments": [], + } + ], + } + + def test_unqualified_name_parses_clauses(self) -> None: + """PredefinedProposer parses select_aggregate_clauses from unqualified FROM.""" + + config = self._make_config("person") + rg = config["tables"]["person"]["row_generators"][0] + gen = PredefinedProposer("person", rg, config) + self.assertIn("mean__age", gen.select_aggregate_clauses()) + self.assertIn("sd__age", gen.select_aggregate_clauses()) + + def test_schema_qualified_name_parses_clauses(self) -> None: + """PredefinedProposer parses select_aggregate_clauses from schema-qualified FROM.""" + + config = self._make_config("myschema.person") + rg = config["tables"]["person"]["row_generators"][0] + gen = PredefinedProposer("person", rg, config) + self.assertIn("mean__age", gen.select_aggregate_clauses()) + self.assertIn("sd__age", gen.select_aggregate_clauses()) + + +class TestContinuousStddevDialect(DatafakerTestCase): + """ContinuousDistributionProposer and LogNormalProposer emit STDEV on MSSQL.""" + + def _make_table(self) -> tuple: + meta = MetaData() + tbl = Table("person", meta, Column("age", Integer())) + return tbl, tbl.c.age + + def test_gaussian_postgresql_uses_stddev(self) -> None: + """GaussianProposer.select_aggregate_clauses uses STDDEV on PostgreSQL.""" + + tbl, col = self._make_table() + proposer = GaussianProposer(tbl, col, MagicMock(), dialect=postgresql.dialect()) + clause = proposer.select_aggregate_clauses()["stddev__age"]["clause"] + self.assert_str_in("STDDEV", clause.upper()) + + def test_gaussian_mssql_uses_stdev(self) -> None: + """GaussianProposer.select_aggregate_clauses uses STDEV on MSSQL.""" + + tbl, col = self._make_table() + proposer = GaussianProposer(tbl, col, MagicMock(), dialect=mssql.dialect()) + clause = proposer.select_aggregate_clauses()["stddev__age"]["clause"] + self.assert_str_in("STDEVP", clause.upper()) + self.assert_str_not_in("STDDEV", clause.upper()) + + def test_lognormal_postgresql_uses_stddev(self) -> None: + """LogNormalProposer.select_aggregate_clauses uses STDDEV on PostgreSQL.""" + + tbl, col = self._make_table() + proposer = LogNormalProposer( + tbl, col, MagicMock(), 1.0, 0.5, dialect=postgresql.dialect() + ) + clause = proposer.select_aggregate_clauses()["logstddev__age"]["clause"] + self.assert_str_in("STDDEV", clause.upper()) + + def test_lognormal_mssql_uses_stdev(self) -> None: + """LogNormalProposer.select_aggregate_clauses uses STDEV on MSSQL.""" + + tbl, col = self._make_table() + proposer = LogNormalProposer( + tbl, col, MagicMock(), 1.0, 0.5, dialect=mssql.dialect() + ) + clause = proposer.select_aggregate_clauses()["logstddev__age"]["clause"] + self.assert_str_in("STDEVP", clause.upper()) + self.assert_str_not_in("STDDEV", clause.upper()) + + +class TestIntervalsDifferenceDialect(DatafakerTestCase): + """SecondsDifference compiles to DATEDIFF on MSSQL and EXTRACT(EPOCH) on PostgreSQL.""" + + def _make_element(self): + return SecondsDifference(literal_column("t1"), literal_column("t2")) + + def test_postgresql_uses_extract_epoch(self) -> None: + """PostgreSQL SecondsDifference uses EXTRACT(EPOCH FROM …).""" + elem = self._make_element() + sql = str(elem.compile(dialect=postgresql.dialect())).upper() + self.assert_str_in("EXTRACT", sql) + self.assert_str_in("EPOCH", sql) + self.assert_str_not_in("DATEDIFF", sql) + + def test_mssql_uses_datediff(self) -> None: + """MSSQL SecondsDifference uses DATEDIFF(second, …).""" + elem = self._make_element() + sql = str(elem.compile(dialect=mssql.dialect())).upper() + self.assert_str_in("DATEDIFF", sql) + self.assert_str_not_in("EXTRACT", sql) + self.assert_str_not_in("EPOCH", sql) + + def test_date_after_proposer_stddev_clause_mssql(self) -> None: + """DateAfterProposer.select_aggregate_clauses uses STDEV and DATEDIFF on MSSQL.""" + + meta = MetaData() + tbl = Table( + "visit", + meta, + Column("start_date", DateTime()), + Column("end_date", DateTime()), + ) + proposer = DateAfterProposer( + metadata=meta, + sd=1.0, + mean=86400.0, + column=tbl.c.end_date, + anchor=tbl.c.start_date, + dialect=mssql.dialect(), + ) + clauses = proposer.select_aggregate_clauses() + mean_clause = clauses["mean__end_date"]["clause"].upper() + sd_clause = clauses["stddev__end_date"]["clause"].upper() + self.assert_str_in("DATEDIFF", mean_clause) + self.assert_str_in("DATEDIFF", sd_clause) + self.assert_str_in("STDEV", sd_clause) + self.assert_str_not_in("STDDEV", sd_clause) + + def test_date_after_proposer_stddev_clause_postgresql(self) -> None: + """DateAfterProposer.select_aggregate_clauses uses STDDEV and EXTRACT on PostgreSQL.""" + + meta = MetaData() + tbl = Table( + "visit", + meta, + Column("start_date", DateTime()), + Column("end_date", DateTime()), + ) + proposer = DateAfterProposer( + metadata=meta, + sd=1.0, + mean=86400.0, + column=tbl.c.end_date, + anchor=tbl.c.start_date, + dialect=postgresql.dialect(), + ) + clauses = proposer.select_aggregate_clauses() + mean_clause = clauses["mean__end_date"]["clause"].upper() + sd_clause = clauses["stddev__end_date"]["clause"].upper() + self.assert_str_in("EXTRACT", mean_clause) + self.assert_str_in("EXTRACT", sd_clause) + self.assert_str_in("STDDEV", sd_clause) + + +class TestAggregateQuerySchemaQualified(DatafakerTestCase): + """_get_aggregate_query qualifies table names using the engine's schema_translate_map.""" + + def _make_engine(self, schema: str | None) -> MagicMock: + engine = MagicMock() + schema_map = {None: schema} if schema else {} + engine.get_execution_options.return_value = {"schema_translate_map": schema_map} + return engine + + def _make_gen(self) -> MagicMock: + gen = MagicMock(spec=Proposer) + gen.select_aggregate_clauses.return_value = { + "mean__age": {"clause": "AVG(age)", "comment": None} + } + return gen + + def test_aggregate_query_includes_schema(self) -> None: + """get_aggregate_query qualifies the bare table name when engine has a schema map.""" + + engine = self._make_engine("myschema") + gen = self._make_gen() + result = get_aggregate_query([gen], "person", engine) + self.assertIsNotNone(result) + self.assert_str_in("myschema.person", result) + + def test_aggregate_query_no_schema(self) -> None: + """get_aggregate_query uses the bare name when no schema is set.""" + + engine = self._make_engine(None) + gen = self._make_gen() + result = get_aggregate_query([gen], "person", engine) + assert result is not None + self.assert_str_in("person", result) + # No schema qualifier (schema.table) should appear after FROM + self.assert_str_not_in( + ".", result.rsplit("FROM ", maxsplit=1)[-1].strip('"').strip() + ) diff --git a/tests/test_interactive_dialect.py b/tests/test_interactive_dialect.py new file mode 100644 index 00000000..35966fec --- /dev/null +++ b/tests/test_interactive_dialect.py @@ -0,0 +1,220 @@ +"""Tests for dialect-correct SQL in interactive shell methods.""" +# pylint: disable=protected-access +import unittest +from unittest.mock import MagicMock + +from sqlalchemy import Column, Integer, MetaData, Table +from sqlalchemy.dialects import mssql, postgresql + +from datafaker.interactive.base import DbCmd +from datafaker.interactive.generators import GeneratorCmd +from datafaker.interactive.table import TableCmd + + +def _make_engine(dialect) -> MagicMock: + """Return a mock engine whose dialect is the given SQLAlchemy dialect instance.""" + engine = MagicMock() + engine.dialect = dialect + conn = MagicMock() + conn.__enter__ = MagicMock(return_value=conn) + conn.__exit__ = MagicMock(return_value=False) + executed = [] + + def capture(stmt, *_args, **_kwargs): + executed.append(stmt) + result = MagicMock() + result.keys.return_value = [] + result.fetchmany.return_value = [] + result.all.return_value = [] + return result + + conn.execute.side_effect = capture + engine.connect.return_value = conn + engine._executed = executed + return engine + + +def _make_table(schema=None) -> Table: + meta = MetaData() + return Table("person", meta, Column("gender_concept_id", Integer()), schema=schema) + + +def _compiled(stmt, dialect) -> str: + return str( + stmt.compile(dialect=dialect, compile_kwargs={"literal_binds": True}) + ).upper() + + +class TestPeekDialect(unittest.TestCase): + """DbCmd.do_peek() uses NEWID/TOP on MS-SQL and RANDOM/LIMIT on PostgreSQL.""" + + def _run_peek(self, dialect_instance, col_names=None, schema=None): + engine = _make_engine(dialect_instance) + shell = MagicMock(spec=DbCmd) + shell.sync_engine = engine + shell.table_index = 0 + shell._table_entries = [MagicMock()] + shell.table_name.return_value = "person" + shell._get_column_names.return_value = col_names or ["gender_concept_id"] + shell.table_metadata.return_value = _make_table(schema=schema) + shell.print_table = MagicMock() + shell.print = MagicMock() + + DbCmd.do_peek(shell, " ".join(col_names) if col_names else "") + return engine._executed, dialect_instance + + def test_mssql_peek_uses_rand_and_top(self) -> None: + """MS-SQL do_peek compiles to NEWID() with TOP.""" + executed, dialect = self._run_peek(mssql.dialect()) + self.assertEqual(len(executed), 1) + sql = _compiled(executed[0], dialect) + self.assertIn(" TOP ", sql) + self.assertIn("NEWID()", sql) + self.assertNotIn("LIMIT", sql) + self.assertNotIn("RANDOM()", sql) + + def test_postgresql_peek_uses_random_and_limit(self) -> None: + """PostgreSQL do_peek compiles to RANDOM() … LIMIT.""" + executed, dialect = self._run_peek(postgresql.dialect()) + self.assertEqual(len(executed), 1) + sql = _compiled(executed[0], dialect) + self.assertIn("RANDOM()", sql) + self.assertIn("LIMIT", sql) + self.assertNotIn("NEWID()", sql) + self.assertNotIn("RAND()", sql) + self.assertNotIn(" TOP ", sql) + self.assertNotIn("ROW_NUMBER()", sql) + + def test_schema_appears_in_from(self) -> None: + """Schema-qualified table name appears in the FROM clause on both dialects.""" + for dialect in (mssql.dialect(), postgresql.dialect()): + with self.subTest(dialect=dialect.name): + executed, d = self._run_peek(dialect, schema="myschema") + sql = _compiled(executed[0], d) + self.assertIn("MYSCHEMA", sql) + + +class TestGetColumnDataDialect(unittest.TestCase): + """Check that GeneratorCmd._get_column_data() produces the correct dialect.""" + + def _run_get_column_data(self, dialect_instance, schema=None): + engine = _make_engine(dialect_instance) + shell = MagicMock(spec=GeneratorCmd) + shell.sync_engine = engine + shell.table_name.return_value = "person" + shell._get_column_names.return_value = ["gender_concept_id"] + shell.table_metadata.return_value = _make_table(schema=schema) + + GeneratorCmd._get_column_data(shell, 5) + return engine._executed, dialect_instance + + def test_mssql_uses_rand_and_top(self) -> None: + """MS-SQL _get_column_data compiles to TOP … NEWID().""" + executed, dialect = self._run_get_column_data(mssql.dialect()) + self.assertEqual(len(executed), 1) + sql = _compiled(executed[0], dialect) + self.assertIn(" TOP ", sql) + self.assertIn("NEWID()", sql) + self.assertNotIn("LIMIT", sql) + self.assertNotIn("RANDOM()", sql) + + def test_postgresql_uses_random_and_limit(self) -> None: + """PostgreSQL _get_column_data compiles to RANDOM() … LIMIT.""" + executed, dialect = self._run_get_column_data(postgresql.dialect()) + self.assertEqual(len(executed), 1) + sql = _compiled(executed[0], dialect) + self.assertIn("RANDOM()", sql) + self.assertIn("LIMIT", sql) + self.assertNotIn("NEWID()", sql) + self.assertNotIn("RAND()", sql) + self.assertNotIn(" TOP ", sql) + self.assertNotIn("ROW_NUMBER()", sql) + + def test_schema_appears_in_from(self) -> None: + """Schema-qualified table name appears in the FROM clause on both dialects.""" + for dialect in (mssql.dialect(), postgresql.dialect()): + with self.subTest(dialect=dialect.name): + executed, d = self._run_get_column_data(dialect, schema="myschema") + sql = _compiled(executed[0], d) + self.assertIn("MYSCHEMA", sql) + + +class TestPrintColumnDataDialect(unittest.TestCase): + """TableCmd.print_column_data() uses NEWID/TOP on MS-SQL and RANDOM/LIMIT on PostgreSQL.""" + + def _run_print_column_data(self, dialect_instance, schema=None): + engine = _make_engine(dialect_instance) + shell = MagicMock(spec=TableCmd) + shell.sync_engine = engine + shell.table_name.return_value = "person" + shell.table_metadata.return_value = _make_table(schema=schema) + shell.columnize = MagicMock() + + TableCmd.print_column_data(shell, "gender_concept_id", 10, 0) + return engine._executed, dialect_instance + + def test_mssql_uses_rand_and_top(self) -> None: + """MS-SQL print_column_data compiles to TOP … NEWID().""" + executed, dialect = self._run_print_column_data(mssql.dialect()) + self.assertEqual(len(executed), 1) + sql = _compiled(executed[0], dialect) + self.assertIn(" TOP ", sql) + self.assertIn("NEWID()", sql) + self.assertNotIn("LIMIT", sql) + self.assertNotIn("RANDOM()", sql) + + def test_postgresql_uses_random_and_limit(self) -> None: + """PostgreSQL print_column_data compiles to RANDOM() … LIMIT.""" + executed, dialect = self._run_print_column_data(postgresql.dialect()) + self.assertEqual(len(executed), 1) + sql = _compiled(executed[0], dialect) + self.assertIn("RANDOM()", sql) + self.assertIn("LIMIT", sql) + self.assertNotIn("RAND()", sql) + self.assertNotIn("NEWID()", sql) + self.assertNotIn(" TOP ", sql) + self.assertNotIn("ROW_NUMBER()", sql) + + def test_schema_appears_in_from(self) -> None: + """Schema-qualified table name appears in the FROM clause on both dialects.""" + for dialect in (mssql.dialect(), postgresql.dialect()): + with self.subTest(dialect=dialect.name): + executed, d = self._run_print_column_data(dialect, schema="myschema") + sql = _compiled(executed[0], d) + self.assertIn("MYSCHEMA", sql) + + +class TestCountsDialect(unittest.TestCase): + """DbCmd.do_counts() compiles a schema-qualified COUNT query.""" + + def _run_counts(self, dialect_instance, schema=None): + engine = _make_engine(dialect_instance) + tbl = _make_table(schema=schema) + shell = MagicMock(spec=DbCmd) + shell.sync_engine = engine + shell._table_entries = [MagicMock()] + shell.table_index = 0 + shell.table_name.return_value = "person" + shell.get_nullable_columns.return_value.name = ["gender_concept_id"] + shell.table_metadata.return_value = tbl + shell.print = MagicMock() + shell.print_table = MagicMock() + + DbCmd.do_counts(shell, "") + return engine._executed, dialect_instance + + def test_counts_schema_appears_in_from(self) -> None: + """do_counts FROM clause includes the schema when one is set.""" + for dialect in (mssql.dialect(), postgresql.dialect()): + with self.subTest(dialect=dialect.name): + executed, d = self._run_counts(dialect, schema="myschema") + self.assertEqual(len(executed), 1) + sql = _compiled(executed[0], d) + self.assertIn("MYSCHEMA", sql) + + def test_counts_no_schema_omits_qualifier(self) -> None: + """do_counts FROM clause has no schema prefix when schema is None.""" + executed, d = self._run_counts(postgresql.dialect(), schema=None) + sql = _compiled(executed[0], d) + self.assertIn("FROM PERSON", sql) + self.assertNotIn("FROM MYSCHEMA", sql) diff --git a/tests/test_interactive_generators.py b/tests/test_interactive_generators.py index b2b3058b..94ee9ffb 100644 --- a/tests/test_interactive_generators.py +++ b/tests/test_interactive_generators.py @@ -10,19 +10,20 @@ import yaml from sqlalchemy import Connection, MetaData, func, select +from datafaker.dialects import SecondsDifference, StdDev from datafaker.interactive.base import DbCmd from datafaker.interactive.generators import GeneratorCmd from datafaker.proposers.choice import ChoiceProposerFactory -from datafaker.proposers.intervals import SecondsDifference from tests.utils import ( + DuckTestDb, GeneratesDBTestCase, + MsSqlTestDb, RequiresDBTestCase, TestDbCmdMixin, - TestDuckDb, ) -class TestGeneratorCmd(GeneratorCmd, TestDbCmdMixin): +class MockGeneratorCmd(GeneratorCmd, TestDbCmdMixin): """GeneratorCmd but mocked""" def get_proposals(self) -> dict[str, tuple[int, str, list[str]]]: @@ -43,9 +44,9 @@ class ConfigureGeneratorsTests(RequiresDBTestCase): database_name = "instrument" schema_name = "public" - def _get_cmd(self, config: MutableMapping[str, Any]) -> TestGeneratorCmd: + def _get_cmd(self, config: MutableMapping[str, Any]) -> MockGeneratorCmd: """Get the command we are using for this test case.""" - return TestGeneratorCmd( + return MockGeneratorCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) @@ -166,7 +167,7 @@ def test_set_generator_distribution(self) -> None: self.assertEqual( gc.config["src-stats"][0]["query"], ( - f"SELECT AVG({column}) AS mean__{column}, STDDEV({column})" + f"SELECT avg({table}.{column}) AS mean__{column}, STDDEV({table}.{column})" f' AS stddev__{column} FROM "{table}"' ), ) @@ -190,7 +191,7 @@ def test_set_generator_distribution_directly(self) -> None: self.assertEqual( gc.config["src-stats"][0]["query"], ( - f"SELECT AVG({column}) AS mean__{column}, STDDEV({column})" + f"SELECT avg({table}.{column}) AS mean__{column}, STDDEV({table}.{column})" f' AS stddev__{column} FROM "{table}"' ), ) @@ -227,9 +228,11 @@ def test_set_generator_choice(self) -> None: self.assertEqual( gc.config["src-stats"][0]["query"], ( - f'SELECT {column} AS value FROM "{table}"' - f" WHERE {column} IS NOT NULL" - f" GROUP BY value ORDER BY COUNT({column}) DESC" + "SELECT _counted.value \n" + f'FROM (SELECT "{column}" AS value, count("{column}") AS count \n' + f"FROM {table} \n" + f'WHERE "{column}" IS NOT NULL GROUP BY "{column}") ' + "AS _counted ORDER BY _counted.count DESC" ), ) @@ -469,8 +472,8 @@ def test_aggregate_queries_merge(self) -> None: { "AVG(frequency) AS mean__frequency", "STDDEV(frequency) AS stddev__frequency", - f"AVG({column}) AS mean__{column}", - f"STDDEV({column}) AS stddev__{column}", + f"avg(string.{column}) AS mean__{column}", + f"STDDEV(string.{column}) AS stddev__{column}", }, ) @@ -583,9 +586,9 @@ class ConfigureGeneratorsWithSrc2Tests(GeneratesDBTestCase): copy_files = ["row_generators.py", "story_generators.py"] copy_from_directory = Path("examples") - def _get_cmd(self, config: MutableMapping[str, Any]) -> TestGeneratorCmd: + def _get_cmd(self, config: MutableMapping[str, Any]) -> MockGeneratorCmd: """Get the command we are using for this test case.""" - return TestGeneratorCmd( + return MockGeneratorCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) @@ -628,7 +631,7 @@ def test_intervals_end_to_end(self) -> None: ) src_result = conn.execute( select( - func.avg(src_diff).label("mean"), func.stddev(src_diff).label("sd") + func.avg(src_diff).label("mean"), StdDev(src_diff).label("sd") ).select_from(self.metadata.tables[table]) ).one() assert self.dst_engine is not None @@ -639,7 +642,7 @@ def test_intervals_end_to_end(self) -> None: ) dst_result = conn.execute( select( - func.avg(dst_diff).label("mean"), func.stddev(dst_diff).label("sd") + func.avg(dst_diff).label("mean"), StdDev(dst_diff).label("sd") ).select_from(self.dst_metadata.tables[table]) ).one() self.assertAlmostEqual( @@ -651,7 +654,14 @@ def test_intervals_end_to_end(self) -> None: class ConfigureGeneratorsWithSrc2DuckDbTests(ConfigureGeneratorsWithSrc2Tests): """Test `configure-generators` with `src2.dump` with DuckDB.""" - database_type = TestDuckDb + database_type = DuckTestDb + + +class ConfigureGeneratorsWithSrc2MsSqlTests(ConfigureGeneratorsWithSrc2Tests): + """Test `configure-generators` with `src2.dump` with DuckDB.""" + + database_type = MsSqlTestDb + schema_name = None class ChoiceMeasurementTableStats: @@ -682,12 +692,12 @@ def setUp(self) -> None: ChoiceProposerFactory.SAMPLE_COUNT = 500 ChoiceProposerFactory.SUPPRESS_COUNT = 5 - def _get_cmd(self, config: MutableMapping[str, Any]) -> TestGeneratorCmd: - return TestGeneratorCmd( + def _get_cmd(self, config: MutableMapping[str, Any]) -> MockGeneratorCmd: + return MockGeneratorCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) - def _propose(self, gc: TestGeneratorCmd) -> dict[str, tuple[int, str, list[str]]]: + def _propose(self, gc: MockGeneratorCmd) -> dict[str, tuple[int, str, list[str]]]: gc.reset() gc.do_propose("") return gc.get_proposals() @@ -838,7 +848,14 @@ def test_create_with_weighted_choice(self) -> None: class GeneratorsOutputTestsDuckDb(GeneratorsOutputTests): """As ``GeneratorsOutputTests`` but with DuckDB.""" - database_type = TestDuckDb + database_type = DuckTestDb + + +class GeneratorsOutputTestsMsSql(GeneratorsOutputTests): + """As ``GeneratorsOutputTests`` but with MS Sql.""" + + database_type = MsSqlTestDb + schema_name = None class GeneratorTests(GeneratesDBTestCase): @@ -848,9 +865,9 @@ class GeneratorTests(GeneratesDBTestCase): database_name = "instrument" schema_name = "public" - def _get_cmd(self, config: MutableMapping[str, Any]) -> TestGeneratorCmd: + def _get_cmd(self, config: MutableMapping[str, Any]) -> MockGeneratorCmd: """We are using configure-generators.""" - return TestGeneratorCmd( + return MockGeneratorCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) @@ -938,7 +955,7 @@ def assert_are_truncated_to(self, xs: Iterable[str], length: int) -> None: def test_varchar_ns_are_truncated(self) -> None: """Tests that mimesis generators for VARCHAR(N) truncate to N characters""" - if self.database_type is TestDuckDb: + if self.database_type is DuckTestDb: # DuckDB does not support limited width VARCHARs return generator = "generic.text.quote" @@ -972,4 +989,11 @@ def test_varchar_ns_are_truncated(self) -> None: class GeneratorTestsDuckDb(GeneratorTests): """As ``GeneratorTests`` but with DuckDB.""" - database_type = TestDuckDb + database_type = DuckTestDb + + +class GeneratorTestsMsSql(GeneratorTests): + """As ``GeneratorTests`` but with M SSql.""" + + database_type = MsSqlTestDb + schema_name = None diff --git a/tests/test_interactive_generators_partitioned.py b/tests/test_interactive_generators_partitioned.py index b7e81334..7d190abc 100644 --- a/tests/test_interactive_generators_partitioned.py +++ b/tests/test_interactive_generators_partitioned.py @@ -8,7 +8,7 @@ from datafaker.interactive.base import DbCmd from datafaker.proposers import NullPartitionedNormalProposerFactory -from tests.test_interactive_generators import TestGeneratorCmd +from tests.test_interactive_generators import MockGeneratorCmd from tests.utils import GeneratesDBTestCase @@ -139,13 +139,13 @@ def setUp(self) -> None: NullPartitionedNormalProposerFactory.SAMPLE_COUNT = 8 NullPartitionedNormalProposerFactory.SUPPRESS_COUNT = 2 - def _get_cmd(self, config: MutableMapping[str, Any]) -> TestGeneratorCmd: + def _get_cmd(self, config: MutableMapping[str, Any]) -> MockGeneratorCmd: """Get the configure-generators object as our command.""" - return TestGeneratorCmd( + return MockGeneratorCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) - def _propose(self, gc: TestGeneratorCmd) -> dict[str, tuple[int, str, list[str]]]: + def _propose(self, gc: MockGeneratorCmd) -> dict[str, tuple[int, str, list[str]]]: gc.reset() gc.do_propose("") return gc.get_proposals() @@ -237,7 +237,7 @@ def populate_measurement_type_vocab(self) -> None: conn.commit() def merge_columns( - self, gc: TestGeneratorCmd, table: str, columns: list[str] + self, gc: MockGeneratorCmd, table: str, columns: list[str] ) -> None: """Merge columns in a table""" gc.do_next(f"{table}.{columns[0]}") diff --git a/tests/test_interactive_missingness.py b/tests/test_interactive_missingness.py index bcbcdbde..c1da7c54 100644 --- a/tests/test_interactive_missingness.py +++ b/tests/test_interactive_missingness.py @@ -10,7 +10,7 @@ from tests.utils import GeneratesDBTestCase, RequiresDBTestCase, TestDbCmdMixin -class TestMissingnessCmd(MissingnessCmd, TestDbCmdMixin): +class MockMissingnessCmd(MissingnessCmd, TestDbCmdMixin): """MissingnessCmd but mocked""" @@ -21,9 +21,9 @@ class ConfigureMissingnessTests(RequiresDBTestCase): database_name = "instrument" schema_name = "public" - def _get_cmd(self, config: MutableMapping[str, Any]) -> TestMissingnessCmd: + def _get_cmd(self, config: MutableMapping[str, Any]) -> MockMissingnessCmd: """We are using configure-missingness.""" - return TestMissingnessCmd( + return MockMissingnessCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) @@ -56,15 +56,19 @@ def test_set_missingness_to_sampled(self) -> None: mc.config["src-stats"][0]["name"], "missing_auto__signature_model__0", ) + q: str = mc.config["src-stats"][0]["query"] + q = q.replace("\n", " ").replace(" ", " ").replace(" ", " ") self.assertEqual( - mc.config["src-stats"][0]["query"], + q, ( - "SELECT COUNT(*) AS row_count," - " player_id__is_null, based_on__is_null FROM" - " (SELECT player_id IS NULL AS player_id__is_null," - " based_on IS NULL AS based_on__is_null FROM" - ' "signature_model" ORDER BY RANDOM() LIMIT 1000)' - " AS __t GROUP BY player_id__is_null, based_on__is_null" + "SELECT count(*) AS row_count," + " __t.player_id__is_null AS player_id__is_null, " + "__t.based_on__is_null AS based_on__is_null FROM" + " (SELECT signature_model.player_id IS NULL AS player_id__is_null," + " signature_model.based_on IS NULL AS based_on__is_null FROM" + " signature_model ORDER BY RANDOM() LIMIT 1000)" + " AS __t GROUP BY __t.player_id__is_null," + " __t.based_on__is_null" ), ) @@ -76,8 +80,8 @@ class ConfigureMissingnessTestsWithGeneration(GeneratesDBTestCase): database_name = "instrument" schema_name = "public" - def _get_cmd(self, config: MutableMapping[str, Any]) -> TestMissingnessCmd: - return TestMissingnessCmd( + def _get_cmd(self, config: MutableMapping[str, Any]) -> MockMissingnessCmd: + return MockMissingnessCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) diff --git a/tests/test_interactive_table.py b/tests/test_interactive_table.py index d2e4b1e6..9ceeeca9 100644 --- a/tests/test_interactive_table.py +++ b/tests/test_interactive_table.py @@ -11,15 +11,15 @@ from tests.utils import RequiresDBTestCase, TestDbCmdMixin -class TestTableCmd(TableCmd, TestDbCmdMixin): +class MockTableCmd(TableCmd, TestDbCmdMixin): """TableCmd but mocked""" class ConfigureTablesTests(RequiresDBTestCase): """Testing configure-tables.""" - def _get_cmd(self, config: MutableMapping[str, Any]) -> TestTableCmd: - return TestTableCmd( + def _get_cmd(self, config: MutableMapping[str, Any]) -> MockTableCmd: + return MockTableCmd( DbCmd.Settings( self.dsn, self.schema_name, @@ -267,13 +267,13 @@ def test_print_data(self) -> None: self.assertEqual(len(tc.column_items), 1) self.assertEqual(len(tc.column_items[0]), to_get_count) tc.reset() - tc.do_data(f"{to_get_count} name 13") + tc.do_data("1000 name 13") self.assertEqual(len(tc.column_items), 1) self.assertEqual( set(tc.column_items[0]), set(filter(lambda n: 13 <= len(n), name_set)) ) tc.reset() - tc.do_data(f"{to_get_count} name 16") + tc.do_data("1000 name 16") self.assertEqual(len(tc.column_items), 1) self.assertEqual( set(tc.column_items[0]), set(filter(lambda n: 16 <= len(n), name_set)) @@ -393,7 +393,7 @@ def test_sanity_checks_warnings_only(self) -> None: }, }, } - with TestTableCmd( + with MockTableCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) as tc: tc.do_next("manufacturer") @@ -437,7 +437,7 @@ def test_sanity_checks_errors_only(self) -> None: }, }, } - with TestTableCmd( + with MockTableCmd( DbCmd.Settings(self.dsn, self.schema_name, config, self.metadata, None) ) as tc: tc.do_next("signature_model") @@ -472,7 +472,7 @@ class TrickyTests(ConfigureTablesTests): database_name = "tricky" schema_name = "public" - def do_and_test_peek_tricky(self, tc: TestTableCmd) -> None: + def do_and_test_peek_tricky(self, tc: MockTableCmd) -> None: """Peek the "names" table and check the output.""" tc.reset() tc.do_peek("") @@ -537,7 +537,7 @@ def test_repeated_field_does_not_throw_exception(self) -> None: """ Select with repeated fields (#70). """ - with TestTableCmd( + with MockTableCmd( DbCmd.Settings( self.dsn, self.schema_name, diff --git a/tests/test_main.py b/tests/test_main.py index 8d80ed6a..340b6ff7 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -12,8 +12,9 @@ from datafaker.settings import Settings, SettingsError from tests.utils import ( DatafakerTestCase, + DuckTestDb, GeneratesDBTestCase, - TestDuckDb, + MsSqlTestDb, get_test_settings, ) @@ -142,7 +143,10 @@ def test_make_tables_errors_if_file_exists( @patch.dict(os.environ, {"SRC_SCHEMA": "myschema"}, clear=True) def test_make_tables_errors_if_src_dsn_missing(self) -> None: """Test the make-tables sub-command refuses to work if SRC_DSN is not set.""" - + self.assertFalse( + (self.get_abs_example_dir() / "does-not-exist.yaml").exists(), + "Precondition failed: tests/examples/does-not-exist.yaml must not exist", + ) self.assertRaises( SettingsError, runner.invoke, @@ -273,7 +277,10 @@ def test_validate_config(self) -> None: """Test the validate-config sub-command.""" result = runner.invoke( app, - ["validate-config", "tests/examples/example_config.yaml"], + [ + "validate-config", + str(self.get_abs_example_dir() / "example_config.yaml"), + ], catch_exceptions=False, ) @@ -283,7 +290,10 @@ def test_validate_config_invalid(self) -> None: """Test the validate-config sub-command.""" result = runner.invoke( app, - ["validate-config", "tests/examples/invalid_config.yaml"], + [ + "validate-config", + str(self.get_abs_example_dir() / "invalid_config.yaml"), + ], catch_exceptions=False, ) @@ -549,4 +559,10 @@ def test_create_primary_key(self) -> None: class TestCliCreateDuckDb(TestsCliCreate): """Tests that use the CLI to generate output in a DuckDB database.""" - database_type = TestDuckDb + database_type = DuckTestDb + + +class TestCliCreateMsSql(TestsCliCreate): + """Tests that use the CLI to generate output in an MS Sql database.""" + + database_type = MsSqlTestDb diff --git a/tests/test_make.py b/tests/test_make.py index d8f99a78..9327ea6a 100644 --- a/tests/test_make.py +++ b/tests/test_make.py @@ -1,6 +1,5 @@ """Tests for the main module.""" import asyncio -import os import tempfile from pathlib import Path from typing import Any @@ -8,14 +7,87 @@ import pandas as pd import yaml -from sqlalchemy import BigInteger, Column, String, select +from sqlalchemy import ( + BigInteger, + Column, + ForeignKey, + Integer, + MetaData, + String, + Table, + select, +) from sqlalchemy.dialects.mysql.types import INTEGER from sqlalchemy.dialects.postgresql import UUID -from datafaker.make import _get_provider_for_column, make_src_stats +from datafaker.make import ( + _get_default_generator, + _get_provider_for_column, + make_src_stats, +) from tests.utils import DatafakerTestCase, GeneratesDBTestCase, RequiresDBTestCase +class TestGetDefaultGenerator(DatafakerTestCase): + """Unit tests for _get_default_generator.""" + + def _make_table(self, *columns: Column) -> Table: + meta = MetaData() + return Table("t", meta, *columns) + + def test_simple_integer_pk_returns_increment(self) -> None: + """Single-column INTEGER PK → DataFaker generates it with increment().""" + table = self._make_table( + Column("id", Integer(), primary_key=True), + Column("val", String()), + ) + gen = _get_default_generator(table.c.id) + assert gen is not None + self.assert_str_in("increment", gen.function_call.function_name) + + def test_simple_biginteger_pk_returns_increment(self) -> None: + """BigInteger PK is also generated by DataFaker with increment().""" + table = self._make_table( + Column("id", BigInteger(), primary_key=True), + Column("val", String()), + ) + gen = _get_default_generator(table.c.id) + assert gen is not None + self.assert_str_in("increment", gen.function_call.function_name) + + def test_composite_pk_not_skipped(self) -> None: + """Columns in a composite PK are not DB-generated and must have a generator.""" + table = self._make_table( + Column("a", Integer(), primary_key=True), + Column("b", Integer(), primary_key=True), + ) + self.assertIsNotNone(_get_default_generator(table.c.a)) + self.assertIsNotNone(_get_default_generator(table.c.b)) + + def test_fk_pk_not_skipped(self) -> None: + """A column that is both PK and FK gets a FK generator, not skipped.""" + meta = MetaData() + Table("parent", meta, Column("id", Integer(), primary_key=True)) + child = Table( + "child", + meta, + Column("parent_id", Integer(), ForeignKey("parent.id"), primary_key=True), + ) + result = _get_default_generator(child.c.parent_id) + assert result is not None + self.assertIn("column_value", result.function_call.function_name) + + def test_non_pk_integer_returns_generator(self) -> None: + """Plain INTEGER column (not a PK) gets a numeric generator.""" + table = self._make_table( + Column("id", Integer(), primary_key=True), + Column("count", Integer()), + ) + result = _get_default_generator(table.c.count) + assert result is not None + self.assertIn("integer_number", result.function_call.function_name) + + class TestMakeGenerators(GeneratesDBTestCase): """Test the make_table_generators function.""" @@ -123,22 +195,15 @@ class TestMakeStats(RequiresDBTestCase): database_name = "src" schema_name = "public" - test_dir = Path("tests/examples") - start_dir = os.getcwd() + use_temporary_cwd = False def setUp(self) -> None: """Pre-test setup.""" super().setUp() - os.chdir(self.test_dir) - conf_path = Path("example_config.yaml") + conf_path = self.get_abs_example_dir() / Path("example_config.yaml") with open(conf_path, "r", encoding="utf8") as f: self.config = yaml.safe_load(f) - def tearDown(self) -> None: - """Post-test cleanup.""" - os.chdir(self.start_dir) - super().tearDown() - def check_make_stats_output(self, src_stats: dict) -> None: """Check that the output of make_src_stats is as expected.""" self.assertSetEqual( @@ -158,7 +223,7 @@ def check_make_stats_output(self, src_stats: dict) -> None: count_names, [ {"num": 1, "name": "Miranda Rando-Generata"}, - {"num": 997, "name": "Randy Random"}, + {"num": 997, "name": "Someone Random"}, {"num": 1, "name": "Testfried Testermann"}, {"num": 1, "name": "Veronica Fyre"}, ], diff --git a/tests/test_proposer.py b/tests/test_proposer.py index d4ea4299..eda47536 100644 --- a/tests/test_proposer.py +++ b/tests/test_proposer.py @@ -2,6 +2,7 @@ import re from pathlib import Path +import duckdb_sqlalchemy import pandas as pd from sqlalchemy import ( Column, @@ -16,12 +17,11 @@ select, text, ) -from sqlalchemy.dialects import postgresql from datafaker.db_utils import create_db_engine, get_sync_engine from datafaker.interactive.generators import get_aggregate_query from datafaker.proposers import ProposerFactory, everything_factory -from datafaker.proposers.base import Proposer, duckdb_workaround +from datafaker.proposers.base import Proposer from tests.utils import DatafakerTestCase select_re = re.compile( @@ -34,7 +34,7 @@ class ProposerUnitTests(DatafakerTestCase): """Proposer test case.""" def test_duckdb_workaround(self) -> None: - """Test the duckdb_workaround function.""" + """Test the duckdb workaround where Tables always get aliased.""" tabname = "tab1" colname = "col1" metadata = MetaData() @@ -42,9 +42,8 @@ def test_duckdb_workaround(self) -> None: column = Column(colname, Text()) table.append_column(column) stmt = select(column) - stmt_a = duckdb_workaround(stmt) - pgd = postgresql.dialect() - sql = stmt_a.compile(dialect=pgd) + ddbd = duckdb_sqlalchemy.Dialect() + sql = stmt.compile(dialect=ddbd, compile_kwargs={"literal_binds": True}) grps = select_re.match(str(sql)) assert grps is not None tcs = grps.group(1).split(".") diff --git a/tests/test_providers.py b/tests/test_providers.py index 68e591e4..2ddd5dbe 100644 --- a/tests/test_providers.py +++ b/tests/test_providers.py @@ -1,9 +1,11 @@ """Tests for the providers module.""" import datetime as dt from typing import Any +from unittest.mock import MagicMock from sqlalchemy import Column, Integer, MetaData, Text, insert -from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.dialects import mssql, postgresql +from sqlalchemy.orm import declarative_base from datafaker import providers from tests.utils import DatafakerTestCase, RequiresDBTestCase @@ -67,6 +69,39 @@ def test_column_value_missing(self) -> None: self.assertIsNone(generated_value) +class ColumnValueRandomFunctionTestCase(DatafakerTestCase): + """column_value uses the correct random function for each dialect.""" + + def _make_connection(self, dialect_name: str) -> MagicMock: + conn = MagicMock() + conn.dialect.name = dialect_name + conn.execute.return_value.first.return_value = None + return conn + + def _get_order_by_sql(self, dialect_name: str) -> str: + conn = self._make_connection(dialect_name) + providers.ColumnValueProvider.column_value(conn, Person, "sex") + query = conn.execute.call_args[0][0] + + dialect = mssql.dialect() if dialect_name == "mssql" else postgresql.dialect() + return str( + query.compile(dialect=dialect, compile_kwargs={"literal_binds": True}) + ) + + def test_mssql_uses_rand(self) -> None: + """Test that the column provider uses RAND for the Postgres dialect.""" + sql = self._get_order_by_sql("mssql") + self.assertIn("newid()", sql.lower()) + self.assertNotIn("random()", sql.lower()) + + def test_postgresql_uses_random(self) -> None: + """Test that the column provider uses RANDOM for the Postgres dialect.""" + sql = self._get_order_by_sql("postgresql") + self.assertIn("random()", sql.lower()) + self.assertNotIn("newid()", sql.lower()) + self.assertNotIn("rand()", sql.lower()) + + class TimedeltaProvider(DatafakerTestCase): """Tests for TimedeltaProvider""" diff --git a/tests/test_serialize_metadata_mssql.py b/tests/test_serialize_metadata_mssql.py new file mode 100644 index 00000000..2c7b3546 --- /dev/null +++ b/tests/test_serialize_metadata_mssql.py @@ -0,0 +1,318 @@ +"""Tests for MS-SQL type support in datafaker.serialize_metadata.""" +# pylint: disable=missing-function-docstring +import unittest + +from sqlalchemy.dialects import mssql, postgresql +from sqlalchemy.sql import sqltypes + +from datafaker.serialize_metadata import dict_to_metadata, type_parser +from datafaker.utils import unqualify_fk_target + + +def parse(type_str: str): + """Shorthand: parse a type string and return the resulting SQLAlchemy type.""" + return type_parser.parse(type_str) + + +class TestMSSQLTypeParser(unittest.TestCase): + """New MS-SQL-specific type strings are parsed correctly.""" + + def test_uniqueidentifier(self) -> None: + result = parse("UNIQUEIDENTIFIER") + self.assertIs(result, mssql.UNIQUEIDENTIFIER) + + def test_datetimeoffset_bare(self) -> None: + result = parse("DATETIMEOFFSET") + self.assertIsInstance(result, mssql.DATETIMEOFFSET) + + def test_datetimeoffset_with_precision(self) -> None: + result = parse("DATETIMEOFFSET(7)") + self.assertIsInstance(result, mssql.DATETIMEOFFSET) + self.assertEqual(result.precision, 7) + + def test_datetime2_bare(self) -> None: + result = parse("DATETIME2") + self.assertIsInstance(result, mssql.DATETIME2) + + def test_datetime2_with_precision(self) -> None: + result = parse("DATETIME2(3)") + self.assertIsInstance(result, mssql.DATETIME2) + self.assertEqual(result.precision, 3) + + def test_varbinary_bare(self) -> None: + result = parse("VARBINARY") + self.assertIsInstance(result, mssql.VARBINARY) + + def test_varbinary_with_length(self) -> None: + result = parse("VARBINARY(8000)") + self.assertIsInstance(result, mssql.VARBINARY) + self.assertEqual(result.length, 8000) + + def test_varbinary_max_lowercase(self) -> None: + result = parse("VARBINARY(max)") + self.assertIsInstance(result, mssql.VARBINARY) + self.assertIsNone(result.length) + + def test_varbinary_max_uppercase(self) -> None: + result = parse("VARBINARY(MAX)") + self.assertIsInstance(result, mssql.VARBINARY) + self.assertIsNone(result.length) + + def test_binary_bare(self) -> None: + result = parse("BINARY") + self.assertIsInstance(result, mssql.BINARY) + + def test_binary_with_length(self) -> None: + result = parse("BINARY(16)") + self.assertIsInstance(result, mssql.BINARY) + self.assertEqual(result.length, 16) + + def test_money(self) -> None: + self.assertIs(parse("MONEY"), mssql.MONEY) + + def test_smallmoney(self) -> None: + self.assertIs(parse("SMALLMONEY"), mssql.SMALLMONEY) + + def test_image(self) -> None: + self.assertIs(parse("IMAGE"), mssql.IMAGE) + + def test_tinyint(self) -> None: + self.assertIs(parse("TINYINT"), mssql.TINYINT) + + def test_smalldatetime(self) -> None: + self.assertIs(parse("SMALLDATETIME"), mssql.SMALLDATETIME) + + def test_ntext(self) -> None: + self.assertIs(parse("NTEXT"), mssql.NTEXT) + + def test_sql_variant(self) -> None: + self.assertIs(parse("SQL_VARIANT"), mssql.SQL_VARIANT) + + def test_rowversion(self) -> None: + self.assertIs(parse("ROWVERSION"), mssql.ROWVERSION) + + +class TestPostgreSQLTypeDegradation(unittest.TestCase): + """PostgreSQL-specific type strings degrade to cross-dialect equivalents.""" + + def test_tsvector_maps_to_text(self) -> None: + result = parse("TSVECTOR") + self.assertIs(result, sqltypes.Text) + + def test_bytea_maps_to_largebinary(self) -> None: + result = parse("BYTEA") + self.assertIs(result, sqltypes.LargeBinary) + + def test_cidr_maps_to_string_43(self) -> None: + result = parse("CIDR") + self.assertIsInstance(result, sqltypes.String) + self.assertEqual(result.length, 43) + + def test_serial_maps_to_integer(self) -> None: + self.assertIs(parse("SERIAL"), sqltypes.INTEGER) + + def test_bigserial_maps_to_bigint(self) -> None: + self.assertIs(parse("BIGSERIAL"), sqltypes.BIGINT) + + def test_smallserial_maps_to_smallint(self) -> None: + self.assertIs(parse("SMALLSERIAL"), sqltypes.SMALLINT) + + +class TestExistingPostgreSQLTypesRoundTrip(unittest.TestCase): # pylint: disable=R0904 + """Pre-existing PostgreSQL type strings still parse correctly (regression tests).""" + + def test_integer(self) -> None: + self.assertIs(parse("INTEGER"), sqltypes.INTEGER) + + def test_bigint(self) -> None: + self.assertIs(parse("BIGINT"), sqltypes.BIGINT) + + def test_smallint(self) -> None: + self.assertIs(parse("SMALLINT"), sqltypes.SMALLINT) + + def test_boolean(self) -> None: + self.assertIs(parse("BOOLEAN"), sqltypes.BOOLEAN) + + def test_float(self) -> None: + self.assertIsInstance(parse("FLOAT"), sqltypes.FLOAT) + + def test_double_precision(self) -> None: + self.assertIs(parse("DOUBLE PRECISION"), sqltypes.DOUBLE_PRECISION) + + def test_numeric_bare(self) -> None: + result = parse("NUMERIC") + self.assertIsInstance(result, sqltypes.NUMERIC) + + def test_numeric_with_args(self) -> None: + result = parse("NUMERIC(10, 2)") + self.assertIsInstance(result, sqltypes.NUMERIC) + self.assertEqual(result.precision, 10) + self.assertEqual(result.scale, 2) + + def test_varchar(self) -> None: + result = parse("VARCHAR(255)") + self.assertIsInstance(result, sqltypes.VARCHAR) + self.assertEqual(result.length, 255) + + def test_varchar_with_mssql_collation(self) -> None: + result = parse("VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS") + self.assertIsInstance(result, sqltypes.VARCHAR) + self.assertEqual(result.length, 50) + self.assertEqual(result.collation, "SQL_Latin1_General_CP1_CI_AS") + + def test_nvarchar_with_mssql_collation(self) -> None: + result = parse("NVARCHAR(100) COLLATE Latin1_General_CI_AS") + self.assertIsInstance(result, sqltypes.NVARCHAR) + self.assertEqual(result.length, 100) + self.assertEqual(result.collation, "Latin1_General_CI_AS") + + def test_char_with_mssql_collation(self) -> None: + result = parse("CHAR(10) COLLATE SQL_Latin1_General_CP1_CI_AS") + self.assertIsInstance(result, sqltypes.CHAR) + self.assertEqual(result.collation, "SQL_Latin1_General_CP1_CI_AS") + + def test_varchar_with_quoted_collation_still_works(self) -> None: + result = parse('VARCHAR(255) COLLATE "fr"') + self.assertIsInstance(result, sqltypes.VARCHAR) + self.assertEqual(result.collation, "fr") + + def test_nvarchar(self) -> None: + result = parse("NVARCHAR(100)") + self.assertIsInstance(result, sqltypes.NVARCHAR) + self.assertEqual(result.length, 100) + + def test_text(self) -> None: + result = parse("TEXT") + self.assertIsInstance(result, sqltypes.TEXT) + + def test_uuid(self) -> None: + self.assertIs(parse("UUID"), sqltypes.UUID) + + def test_date(self) -> None: + self.assertIs(parse("DATE"), sqltypes.DATE) + + def test_datetime(self) -> None: + self.assertIs(parse("DATETIME"), sqltypes.DATETIME) + + def test_timestamp_bare(self) -> None: + self.assertIs(parse("TIMESTAMP"), sqltypes.TIMESTAMP) + + def test_timestamp_with_timezone(self) -> None: + result = parse("TIMESTAMP WITH TIME ZONE") + self.assertIsInstance(result, postgresql.types.TIMESTAMP) + self.assertTrue(result.timezone) + + def test_timestamp_with_precision_and_timezone(self) -> None: + result = parse("TIMESTAMP(6) WITH TIME ZONE") + self.assertIsInstance(result, postgresql.types.TIMESTAMP) + self.assertEqual(result.precision, 6) + self.assertTrue(result.timezone) + + def test_timestamp_without_timezone(self) -> None: + # WITHOUT TIME ZONE means timezone=False; the parser returns the plain + # sqltypes.TIMESTAMP class (not a pg-specific instance) in this case. + result = parse("TIMESTAMP WITHOUT TIME ZONE") + self.assertIs(result, sqltypes.TIMESTAMP) + + def test_time_bare(self) -> None: + self.assertIs(parse("TIME"), sqltypes.TIME) + + def test_time_with_timezone(self) -> None: + result = parse("TIME WITH TIME ZONE") + self.assertIsInstance(result, postgresql.types.TIME) + self.assertTrue(result.timezone) + + def test_bit_bare(self) -> None: + result = parse("BIT") + self.assertIsInstance(result, postgresql.BIT) + + def test_bit_with_length(self) -> None: + result = parse("BIT(8)") + self.assertIsInstance(result, postgresql.BIT) + self.assertEqual(result.length, 8) + + def test_real_bare(self) -> None: + result = parse("REAL") + self.assertIsInstance(result, sqltypes.REAL) + + def test_blob(self) -> None: + self.assertIs(parse("BLOB"), sqltypes.BLOB) + + def test_clob(self) -> None: + self.assertIs(parse("CLOB"), sqltypes.CLOB) + + +class TestArrayType(unittest.TestCase): + """Array types (PostgreSQL-specific) still parse correctly.""" + + def test_integer_array(self) -> None: + result = parse("INTEGER[]") + self.assertIsInstance(result, postgresql.ARRAY) + self.assertEqual(result.dimensions, 1) + + def test_text_array(self) -> None: + result = parse("TEXT[]") + self.assertIsInstance(result, postgresql.ARRAY) + + def test_multidimensional_array(self) -> None: + result = parse("INTEGER[][]") + self.assertIsInstance(result, postgresql.ARRAY) + self.assertEqual(result.dimensions, 2) + + +class TestUnqualifyFkTarget(unittest.TestCase): + """Schema prefix is stripped from 3-part FK targets.""" + + def test_three_part_target_drops_schema(self) -> None: + self.assertEqual( + unqualify_fk_target("mimic100.concept.concept_id"), "concept.concept_id" + ) + + def test_two_part_target_unchanged(self) -> None: + self.assertEqual( + unqualify_fk_target("concept.concept_id"), "concept.concept_id" + ) + + def test_single_part_unchanged(self) -> None: + self.assertEqual(unqualify_fk_target("concept_id"), "concept_id") + + +class TestSchemaQualifiedFKResolution(unittest.TestCase): + """Schema-qualified FK targets resolve correctly when building MetaData.""" + + def test_schema_qualified_fk_resolves_in_metadata(self) -> None: + """Test that foreign keys resolve correctly in generated MetaData.""" + orm_dict = { + "tables": { + "concept": { + "columns": { + "concept_id": { + "type": "BIGINT", + "primary": True, + "nullable": False, + }, + } + }, + "person": { + "columns": { + "person_id": { + "type": "BIGINT", + "primary": True, + "nullable": False, + }, + "gender_concept_id": { + "type": "BIGINT", + "primary": False, + "nullable": False, + "foreign_keys": ["myschema.concept.concept_id"], + }, + } + }, + } + } + meta = dict_to_metadata(orm_dict) + person = meta.tables["person"] + fks = list(person.c.gender_concept_id.foreign_keys) + self.assertEqual(len(fks), 1) + # FK target should resolve to the concept table without raising NoReferencedTableError + self.assertEqual(fks[0].column.table.name, "concept") diff --git a/tests/test_unique_generator.py b/tests/test_unique_generator.py index b2c17ddf..01efd6b3 100644 --- a/tests/test_unique_generator.py +++ b/tests/test_unique_generator.py @@ -2,7 +2,7 @@ from unittest.mock import MagicMock from sqlalchemy import Boolean, Column, Integer, Text, UniqueConstraint, insert -from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import declarative_base from datafaker.unique_generator import UniqueGenerator from tests.utils import RequiresDBTestCase @@ -13,7 +13,7 @@ metadata = Base.metadata -class TestTable(Base): +class MockTable(Base): """A test SQLAlchemy table.""" __tablename__ = "test_table" @@ -42,7 +42,7 @@ def setUp(self) -> None: def test_unique_generator_empty_table(self) -> None: """Test finding non-conflicting values for an empty database.""" - table_name = TestTable.__tablename__ + table_name = MockTable.__tablename__ uniq_ab = UniqueGenerator(["a", "b"], table_name) uniq_c = UniqueGenerator(["c"], table_name, max_tries=10) @@ -70,7 +70,7 @@ def test_unique_generator_nonempty_table(self) -> None: running create-data when there already is data in the database. """ - table_name = TestTable.__tablename__ + table_name = MockTable.__tablename__ uniq_ab = UniqueGenerator(["a", "b"], table_name) uniq_c = UniqueGenerator(["c"], table_name, max_tries=10) @@ -80,7 +80,7 @@ def test_unique_generator_nonempty_table(self) -> None: string1 = "String 1" string2 = "String 2" conn.execute( - insert(TestTable).values(a=test_ab1[0], b=test_ab1[1], c=string1) + insert(MockTable).values(a=test_ab1[0], b=test_ab1[1], c=string1) ) # First check a value that doesn't conflict with the one we just wrote, then # the one that does. @@ -96,7 +96,7 @@ def test_unique_generator_multivalue_generator(self) -> None: values. """ - table_name = TestTable.__tablename__ + table_name = MockTable.__tablename__ uniq_ab = UniqueGenerator(["a", "b"], table_name) uniq_c = UniqueGenerator(["c"], table_name, max_tries=10) @@ -128,7 +128,7 @@ def test_unique_generator_max_tries(self) -> None: """Test that UniqueGenerator the max_tries argument is respected.""" max_tries = 23 - table_name = TestTable.__tablename__ + table_name = MockTable.__tablename__ uniq_ab = UniqueGenerator(["a", "b"], table_name, max_tries=max_tries) mock_generator = MagicMock() test_val = (True, False, "String 1") diff --git a/tests/test_utils_mssql.py b/tests/test_utils_mssql.py new file mode 100644 index 00000000..5e27cd8f --- /dev/null +++ b/tests/test_utils_mssql.py @@ -0,0 +1,163 @@ +"""Tests for MS-SQL driver support helpers in datafaker.utils.""" +import unittest +from unittest.mock import MagicMock, patch + +from sqlalchemy.engine import make_url + +from datafaker.db_utils import create_db_engine, get_metadata, get_sync_engine +from datafaker.utils import make_async_dsn +from tests.utils import DatafakerTestCase, MsSqlTestDb + + +class TestMakeAsyncDsn(unittest.TestCase): + """Tests for make_async_dsn.""" + + def _call(self, dsn: str) -> str: + return make_async_dsn(dsn) + + def test_postgresql_bare_dialect(self) -> None: + """postgresql:// is rewritten to use asyncpg.""" + result = self._call("postgresql://user:pass@host:5432/db") + self.assertTrue( + result.startswith("postgresql+asyncpg://"), + f"Expected asyncpg driver, got: {result}", + ) + + def test_postgresql_with_existing_driver(self) -> None: + """postgresql+psycopg2:// is also rewritten to asyncpg.""" + result = self._call("postgresql+psycopg2://user:pass@host:5432/db") + self.assertTrue(result.startswith("postgresql+asyncpg://")) + + def test_postgresql_preserves_credentials_and_path(self) -> None: + """Host, port and database name are preserved (password is masked in repr).""" + + result_url = make_url(self._call("postgresql://alice:secret@dbhost:5433/mydb")) + self.assertEqual(result_url.host, "dbhost") + self.assertEqual(result_url.port, 5433) + self.assertEqual(result_url.database, "mydb") + self.assertEqual(result_url.username, "alice") + + def test_mssql_bare_dialect(self) -> None: + """mssql:// is rewritten to use aioodbc.""" + result = self._call("mssql://user:pass@host:1433/db") + self.assertTrue( + result.startswith("mssql+aioodbc://"), + f"Expected aioodbc driver, got: {result}", + ) + + def test_mssql_with_existing_driver(self) -> None: + """mssql+pyodbc:// is rewritten to aioodbc.""" + result = self._call("mssql+pyodbc://user:pass@host:1433/db") + self.assertTrue(result.startswith("mssql+aioodbc://")) + + def test_unknown_dialect_raises(self) -> None: + """An unknown dialect raises ValueError rather than silently producing a bad DSN.""" + with self.assertRaises(ValueError) as ctx: + self._call("oracle://user:pass@host:1521/db") + self.assertIn("oracle", str(ctx.exception)) + + def test_duckdb_raises(self) -> None: + """DuckDB DSNs are not async-capable and should raise.""" + with self.assertRaises(ValueError): + self._call("duckdb:///path/to/file.db") + + +class TestSchemaTranslateMap(DatafakerTestCase): + """Tests for the cross-dialect schema routing in create_db_engine.""" + + def _make_engine(self, dsn: str, schema_name: str | None = None): + return get_sync_engine(create_db_engine(dsn, schema_name=schema_name)) + + def test_no_schema_no_translate_map(self) -> None: + """Without a schema_name, schema_translate_map is absent from execution options.""" + engine = self._make_engine("duckdb:///:memory:") + opts = engine.get_execution_options() + self.assertNotIn("schema_translate_map", opts) + + def test_schema_sets_translate_map(self) -> None: + """When schema_name is given, MSSQL uses schema_translate_map (not search_path).""" + try: + engine = self._make_engine( + MsSqlTestDb.get_test_db_dsn(), schema_name="myschema" + ) + except Exception: # pylint: disable=W0718 + self.skipTest("mssql+pyodbc driver not available in this environment") + opts = engine.get_execution_options() + self.assertIn("schema_translate_map", opts) + self.assertEqual(opts["schema_translate_map"], {None: "myschema"}) + + def test_duckdb_parquet_dir_sets_search_path(self) -> None: + """For DuckDB, parquet_dir is applied via file_search_path session setting.""" + + parq_dir = self.get_abs_example_dir() / "duckdb" + with patch("datafaker.db_utils.set_db_settings") as mock_set: + engine = get_sync_engine( + create_db_engine( + "duckdb:///:memory:", schema_name="myschema", parquet_dir=parq_dir + ) + ) + # Force a connection so the connect-event handler fires + with engine.connect() as conn: + conn.execute(__import__("sqlalchemy").text("SELECT 1")) + + calls = mock_set.call_args_list + self.assertTrue(calls, "set_db_settings should have been called at least once") + settings_passed = ( + calls[0].args[1] + if len(calls[0].args) > 1 + else calls[0].kwargs.get("settings", {}) + ) + self.assertIn("file_search_path", settings_passed) + self.assertEqual(settings_passed["file_search_path"], f"'{parq_dir}'") + + def test_mssql_dsn_schema_sets_translate_map(self) -> None: + """schema_translate_map is set even for an MS-SQL DSN (engine creation, no connect).""" + + # create_engine with mssql+pyodbc does not connect at construction time, + # so this is safe to run even without an ODBC driver installed. + try: + engine = get_sync_engine( + create_db_engine( + "mssql+pyodbc://user:pass@host/db?driver=ODBC+Driver+18+for+SQL+Server", + schema_name="dbo", + ) + ) + except Exception: # pylint: disable=W0718 + self.skipTest("mssql+pyodbc driver not available in this environment") + + opts = engine.get_execution_options() + self.assertEqual(opts.get("schema_translate_map"), {None: "dbo"}) + + +class TestGetMetadataSchema(unittest.TestCase): + """Tests for the schema_name parameter on get_metadata.""" + + def test_reflect_called_with_schema(self) -> None: + """get_metadata passes schema_name to MetaData.reflect.""" + + mock_engine = MagicMock() + mock_engine.connect.return_value.__enter__ = MagicMock(return_value=MagicMock()) + mock_engine.connect.return_value.__exit__ = MagicMock(return_value=False) + + with patch("datafaker.db_utils.MetaData") as mock_meta_data: + mock_md = MagicMock() + mock_meta_data.return_value = mock_md + mock_md.reflect.return_value = None + + get_metadata(mock_engine, schema_name="myschema") + + mock_md.reflect.assert_called_once_with(mock_engine, schema="myschema") + + def test_reflect_called_without_schema_when_none(self) -> None: + """get_metadata passes schema=None to reflect when no schema_name is given.""" + + mock_engine = MagicMock() + + with patch("datafaker.db_utils.MetaData") as mock_meta_data: + mock_md = MagicMock() + mock_meta_data.return_value = mock_md + mock_md.reflect.return_value = None + + get_metadata(mock_engine) + + mock_md.reflect.assert_called_once_with(mock_engine, schema=None) diff --git a/tests/utils.py b/tests/utils.py index 427ba670..bcce496a 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -9,7 +9,7 @@ import time import traceback from abc import ABC, abstractmethod -from collections.abc import MutableSequence, Sequence +from collections.abc import MutableSequence, Sequence, Set from functools import lru_cache from importlib import resources from pathlib import Path @@ -19,9 +19,12 @@ from unittest import SkipTest, TestCase import duckdb +import sqlalchemy import testing.postgresql import yaml -from sqlalchemy import Engine, MetaData +from prettytable import PrettyTable +from sqlalchemy import Engine, MetaData, create_engine +from sqlalchemy.engine import make_url from sqlalchemy_utils import create_database from datafaker import settings @@ -91,20 +94,27 @@ def get_dsn(self, database_name: str | None) -> str: def run_sql(self, sql_file: Path) -> None: """Run the provided SQL file on the test database.""" - def create_empty(self, name: str) -> str: + def create_empty( # pylint: disable=unused-argument + self, + name: str, + schema_name: str | None, + ) -> None: """Create an empty database and return the DSN string.""" dsn = self.get_dsn(name) create_database(dsn) - return dsn -class TestPostgres(TestDatabaseBase): +class PostgresTestDb(TestDatabaseBase): """Postgres test database.""" Postgresql = None @classmethod def skip(cls) -> str | None: + try: + import psycopg2 as _psycopg2 # noqa: F401 pylint: disable=import-outside-toplevel + except ImportError: + return "psycopg2 not installed; run: poetry install --all-extras" if shutil.which("psql"): return None return "need to find 'psql': install PostgreSQL to enable" @@ -172,7 +182,7 @@ def run_sql(self, sql_file: Path) -> None: assert completed_process.stderr == b"", completed_process.stderr -class TestDuckDb(TestDatabaseBase): +class DuckTestDb(TestDatabaseBase): """Test DuckDB database.""" SQL_REMOVALS_RE = re.compile( @@ -189,7 +199,7 @@ def skip(cls) -> str | None: return None def __init__(self, *args: Any, **kwargs: Any) -> None: - """Initialize TestDuckDb""" + """Initialize DuckTestDb""" super().__init__(*args, **kwargs) self._duckdb_con: Any = None self._db_dir = Path(mkdtemp("duck")) @@ -237,13 +247,217 @@ def run_sql(self, sql_file: Path) -> None: duckdb_con.execute(sanitized) duckdb_con.close() - def create_empty(self, name: str) -> str: + def create_empty( # pylint: disable=unused-argument + self, + name: str, + schema_name: str | None, + ) -> None: """ The standard SQLAlchemy database creation tool doesn't work for DuckDB. Thankfully, it is not necessary either. """ - return self.get_dsn(name) + return + + +class MsSqlTestDb(TestDatabaseBase): + """MS-SQL Server test database. + + Requires the ``MSSQL_TEST_DSN`` environment variable to be set to a + ``mssql+pyodbc://`` connection string pointing at a running SQL Server + instance (e.g. the docker-compose ``mssql`` service). + + Tests that use this class are skipped automatically when the variable is + absent or when a connection cannot be established. + """ + + _ENV_VAR = "MSSQL_TEST_DSN" + _base_dsn: str = "" + _CREATE_DATABASE_RE = re.compile(r"CREATE\s+DATABASE\s+([A-Za-z0-9_]+)\s+WITH\s.*;") + _ALTER_DATABASE_RE = re.compile( + r"ALTER\s+DATABASE\s+([A-Za-z0-9_]+)\s+OWNER\s+TO\s.*;" + ) + _CONNECT_RE = re.compile(r"^\\connect\s+([A-Za-z0-9_]+)\s*$", re.MULTILINE) + _PUBLIC_SCHEMA = re.compile(r"(\s)public\.") + _GO_RE = re.compile(r"^\s*GO\s*$", re.MULTILINE) + _EOL_RE = re.compile(r";$", re.MULTILINE) + _TIMESTAMP_RE = re.compile(r"(TIMESTAMP)\s+WITH\s+TIME\s+ZONE", re.IGNORECASE) + _ALTER_OWNER_RE = re.compile( + r"ALTER\s+(TABLE|DATABASE)\s+[A-Za-z0-9_.]+\s+OWNER\s+TO\s+[A-Za-z0-9_]+\s*;" + ) + _ALTER_ONLY_RE = re.compile(r"ALTER\s+TABLE\s+ONLY\s+") + _CREATE_INDEX_RE = re.compile( + r"(CREATE\s+INDEX\s+[A-Za-z0-9_.]+\s+ON\s+[A-Za-z0-9_.]+\s+)" + r"USING\s+[A-Za-z0-9_.]+\s+(\([A-Za-z0-9_., ]+\))\s*;" + ) + _BOOLEAN_RE = re.compile(r"\bboolean\b", re.IGNORECASE) + _TRUE_RE = re.compile(r"\btrue\b", re.IGNORECASE) + _FALSE_RE = re.compile(r"\bfalse\b", re.IGNORECASE) + _UUID_RE = re.compile(r"\buuid\b", re.IGNORECASE) + _TEXT_RE = re.compile(r"\btext\b", re.IGNORECASE) + + @classmethod + def get_test_db_dsn(cls) -> str: + """Get the DSN for the master database to connect to.""" + return os.environ.get( + cls._ENV_VAR, + "mssql+pyodbc://sa:Datafaker!Test123" + "@127.0.0.1:21433/master" + "?driver=ODBC+Driver+18+for+SQL+Server" + "&TrustServerCertificate=yes", + ) + + @classmethod + def skip(cls) -> str | None: + """Return a skip message if SQL Server is not reachable.""" + dsn = cls.get_test_db_dsn() + try: + import pyodbc as _pyodbc # noqa: F401 pylint: disable=import-outside-toplevel + except ImportError: + return "pyodbc not installed; run: poetry install --all-extras" + try: + with create_engine(dsn).connect(): + pass + except Exception as exc: # pylint: disable=broad-except + return f"cannot connect to MS-SQL ({exc})" + return None + + @classmethod + def setup(cls) -> None: + """Store the base DSN for use by all instances.""" + cls._base_dsn = cls.get_test_db_dsn() + + def _generate_prefix(self) -> None: + self.prefix = f"tmp{''.join(random.choices(string.digits, k=3))}_" + + def __init__(self): + super().__init__() + self.db_names = [] + self._generate_prefix() + + def open(self) -> None: + """Nothing to open — SQL Server runs externally.""" + self._generate_prefix() + + def close(self) -> None: + self._drop_databases_then(self.db_names, []) + self.db_names = [] + + def get_dsn(self, database_name: str | None) -> str: + """Return a DSN pointing at ``database_name`` within the SQL Server instance.""" + if not database_name: + return self._base_dsn + + url = make_url(self._base_dsn) + return url.set(database=self.prefix + database_name).render_as_string( + hide_password=False + ) + + def _get_connection_string(self, db_name: str) -> str: + """Get a connection string for the named database.""" + url = make_url(self._base_dsn) + return ( + f"DRIVER={{ODBC Driver 18 for SQL Server}};" + f"SERVER={url.host},{url.port or 21433};" + f"DATABASE={db_name};" + f"UID={url.username};PWD={url.password};" + "TrustServerCertificate=yes;" + ) + + def _drop_databases_then(self, db_names: list[str], execs: list[str]) -> None: + """Drop the database ``db_name`` and maybe execute a command.""" + import pyodbc # noqa: F401 pylint: disable=import-outside-toplevel + + conn_str = self._get_connection_string("master") + with pyodbc.connect( # pylint: disable=c-extension-no-member + conn_str, + autocommit=True, + ) as conn: + conn.execute("USE master") + for db_name in db_names: + conn.execute( + f"""IF DB_ID('{db_name}') IS NOT NULL +BEGIN + ALTER DATABASE [{db_name}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; + DROP DATABASE [{db_name}]; +END""" + ) + for ex in execs: + sql = ex.strip() + if sql: + conn.execute(sql) + + def create_empty(self, name: str, schema_name: str | None) -> None: + """Drop (if exists) and create a fresh SQL Server database named ``name``.""" + import pyodbc # noqa: F401 pylint: disable=import-outside-toplevel + + qname = self.prefix + name + instructions = [ + f"CREATE DATABASE [{qname}]", + f"USE [{qname}]", + ] + if schema_name: + instructions.append(f"CREATE SCHEMA [{schema_name}]") + self._drop_databases_then([qname], instructions) + self.db_names.append(qname) + + # SQL Server can take a moment to bring the new database fully online. + # Poll until a connection succeeds rather than returning a DSN that + # immediately produces TCP resets. + db_conn_str = self._get_connection_string(qname) + deadline = time.monotonic() + 30 + + while True: + try: + with pyodbc.connect( # pylint: disable=c-extension-no-member + db_conn_str, + autocommit=True, + timeout=5, + ) as probe: + probe.execute("SELECT 1") + break + except pyodbc.Error: # pylint: disable=c-extension-no-member + if time.monotonic() > deadline: + raise + time.sleep(0.5) + + def run_sql(self, sql_file: Path) -> None: + """Execute a T-SQL file via pyodbc, splitting batches on GO.""" + sql = sql_file.read_text(encoding="utf-8") + # Which databases are we creating? + db_names = self._CREATE_DATABASE_RE.findall(sql) + self.db_names = [self.prefix + name for name in db_names] + # Get rid of parameters MSSQL does not understand + sql = self._CREATE_DATABASE_RE.sub( + f"CREATE DATABASE {self.prefix}\\1;\nGO\n", sql + ) + # Get rid of ownership change + sql = self._ALTER_DATABASE_RE.sub("", sql) + # Turn \connect into USE + sql = self._CONNECT_RE.sub(f"USE {self.prefix}\\1;", sql) + # Get rid of public. (preceded by space) + sql = self._PUBLIC_SCHEMA.sub("\\1", sql) + # Get rid of WITH TIME ZONE + sql = self._TIMESTAMP_RE.sub("DATETIME2", sql) + # Get rid of changing owner + sql = self._ALTER_OWNER_RE.sub("", sql) + # Get rid of ONLY + sql = self._ALTER_ONLY_RE.sub("ALTER TABLE ", sql) + # Get USING out of CREATE INDEX + sql = self._CREATE_INDEX_RE.sub("\\1\\2;", sql) + # BOOLEAN -> BIT + sql = self._BOOLEAN_RE.sub("BIT", sql) + sql = self._TRUE_RE.sub("1", sql) + sql = self._FALSE_RE.sub("0", sql) + # UUID -> UNIQUEIDENTIFIER + sql = self._UUID_RE.sub("UNIQUEIDENTIFIER", sql) + # TEXT -> NVARCHAR(450), the largest unicode text that have a unique constaint + sql = self._TEXT_RE.sub("NVARCHAR(450)", sql) + sql = self._EOL_RE.sub(";\nGO", sql) + self._drop_databases_then( + self.db_names, + self._GO_RE.split(sql), + ) class DatafakerTestCase(TestCase): @@ -335,7 +549,7 @@ def assert_greater_and_not_none(self, left: float | None, right: float) -> None: else: self.assertGreater(left, right) - def assert_subset(self, set1: set[T], set2: set[T], msg: str | None = None) -> None: + def assert_subset(self, set1: Set[T], set2: Set[T], msg: str | None = None) -> None: """Assert a set is a (non-strict) subset. :param set1: The asserted subset. @@ -344,7 +558,7 @@ def assert_subset(self, set1: set[T], set2: set[T], msg: str | None = None) -> N differences. """ try: - difference = set1.difference(set2) + difference = set1 - set2 except TypeError as e: self.fail(f"invalid type when attempting set difference: {e}") except AttributeError as e: @@ -362,6 +576,48 @@ def assert_subset(self, set1: set[T], set2: set[T], msg: str | None = None) -> N standard_msg = "\n".join(lines) self.fail(self._formatMessage(msg, standard_msg)) + def assert_str_in(self, needle: str | None, haystack: str | None) -> None: + """Assert that the string ``needle`` is in the string ``haystack``.""" + if needle is None or haystack is None or needle not in haystack: + self.fail(f"Expected {repr(needle)} to be found in {repr(haystack)}") + + def assert_str_not_in(self, needle: str, haystack: str) -> None: + """Assert that the string ``needle`` is not in the string ``haystack``.""" + if needle in haystack: + pos = haystack.index(needle) + length = len(needle) + trimmed = haystack + if 120 < len(haystack): + if 50 < pos: + trimmed = "... " + trimmed[pos - 46 :] + pos = 50 + if 120 < len(trimmed): + trimmed = trimmed[:116] + " ..." + if 117 < pos + length: + length = 117 - pos + self.fail( + f'Expected "{needle}" not to be found but:\n' + + f"{trimmed}\n{' ' * pos}{'^' * length}" + ) + + +def print_sql_results(engine: Engine, sql: str) -> None: + """ + Pretty print the result of some sql. + """ + with engine.connect() as conn: + results = conn.execute(sqlalchemy.text(sql)).fetchall() + if len(results) == 0: + print("No results returned") + return + pt = PrettyTable(results[0]._fields) + to_print = min(len(results), 20) + pt.add_rows(results[:to_print]) # type: ignore + print(pt) + skipped = len(results) - to_print + if skipped: + print(f"... and {skipped} more rows") + class RequiresDBTestCase( DatafakerTestCase @@ -376,7 +632,7 @@ class RequiresDBTestCase( reflected from that engine. """ - database_type: type[TestDatabaseBase] = TestPostgres + database_type: type[TestDatabaseBase] = PostgresTestDb dst_schema_name: str | None = None @classmethod @@ -410,6 +666,15 @@ def dst_dsn(self) -> str: assert self.dst_database is not None return self.dst_database.get_dsn(self.dst_name) + def _create_engine(self) -> None: + assert self.database is not None + self.engine = create_db_engine( + self.database.get_dsn(self.database_name), + schema_name=self.schema_name, + use_asyncio=self.use_asyncio, + ) + self.sync_engine = get_sync_engine(self.engine) + def setUp(self) -> None: super().setUp() if self.database is None: @@ -418,24 +683,29 @@ def setUp(self) -> None: self.database.open() if self.dump_file_path is not None: self.database.run_sql(self.get_abs_example_dir() / self.dump_file_path) - self.engine = create_db_engine( - self.database.get_dsn(self.database_name), - schema_name=self.schema_name, - use_asyncio=self.use_asyncio, - ) - self.sync_engine = get_sync_engine(self.engine) + self._create_engine() self.metadata.reflect(self.sync_engine) - def make_destination_database(self, name: str) -> None: - """Make an empty destination database.""" - self.dst_name = name - if self.dst_database is None: - self.dst_database = self.database_type() + def sql(self, sql: str) -> None: + """ + Execute some SQL against the source database. + + This method is useful during debugging. + """ + print_sql_results(self.sync_engine, sql) + + def dst_sql(self, sql: str) -> None: + """ + Execute some SQL against the destination database. + + This method is useful during debugging. + """ + if self.dst_engine is not None: + print_sql_results(self.dst_engine, sql) else: - self.dst_database.open() - dsn = self.dst_database.create_empty(name) - # Check that our programmatic way of getting the DSN works - assert dsn == self.dst_dsn + print("No destination engine") + + def _create_engine_dst(self): self.dst_engine = get_sync_engine( create_db_engine_dst( self.dst_dsn, @@ -444,11 +714,25 @@ def make_destination_database(self, name: str) -> None: ) ) + def make_destination_database(self, name: str) -> None: + """Make an empty destination database.""" + self.dst_name = name + if self.dst_database is None: + self.dst_database = self.database_type() + else: + self.dst_database.open() + self.dst_database.create_empty(name, self.dst_schema_name) + self._create_engine_dst() + def tearDown(self) -> None: assert self.database is not None - self.database.close() + if hasattr(self, "sync_engine"): + self.sync_engine.dispose() + if self.dst_engine is not None: + self.dst_engine.dispose() if self.dst_database is not None: self.dst_database.close() + self.database.close() super().tearDown() @property @@ -536,7 +820,7 @@ def generate_data( self, config: Mapping[str, Any], num_passes: int = 1 ) -> Mapping[str, Any]: """ - Replaces the DB's source data with generated data. + Replaces the destination DB's data with fresh generated data. :return: A Python dictionary representation of the src-stats.yaml file, for what it's worth. """ self.set_configuration(config)