def wrap(fn): table_definition = OrderedProperties() fn(table_definition) table = Table(table_name, g.db_meta) for attrname in table_definition.keys(): value = table_definition[attrname] if isinstance(value, Column): table.append_column(value) elif isinstance(value, Constraint): table.append_constraint(value) table.create(g.db_engine)
def visit_table(self, table_obj, schema_obj): self.check_table(table_obj, schema_obj) columns = [self.visit_column(c, table_obj) for c in table_obj["columns"]] name = table_obj["name"] table_id = table_obj["@id"] description = table_obj.get("description") schema_name = self.schema_name or schema_obj["name"] table = Table( name, self.metadata, *columns, schema=schema_name, comment=description ) primary_key = self.visit_primary_key(table_obj.get("primaryKey", []), table_obj) if primary_key: table.append_constraint(primary_key) primary_key = self.visit_primary_key(table_obj.get("primaryKey"), table) if primary_key: table.append_constraint(primary_key) constraints = [self.visit_constraint(c, table) for c in table_obj.get("constraints", [])] for constraint in constraints: table.append_constraint(constraint) indexes = [self.visit_index(i, table) for i in table_obj.get("indexes", [])] for index in indexes: # FIXME: Hack because there's no table.add_index index._set_parent(table) table.indexes.add(index) self.graph_index[table_id] = table
def table_factory(draw: Callable[[Strategy], Any]) -> Table: extends_existing = draw(extend_existing) table_names = names if not extends_existing: table_names = (table_names.filter( lambda identifier: identifier not in metadata.tables)) table_name = draw(table_names) columns_list = draw(columns_lists) if extends_existing and table_name in metadata.tables: # preserving constraints, especially primary key one existing_table = metadata.tables[table_name] columns_list = [ existing_table.c.get(column.name, column) for column in columns_list ] result = Table(table_name, metadata, *columns_list, extend_existing=extends_existing) constraints = draw( constrained.lists_factory(columns_list, primary_key_min_size=1)) for constraint in constraints: result.append_constraint(constraint) return result
def _test_get_unique_constraints(self, schema=None): # SQLite dialect needs to parse the names of the constraints # separately from what it gets from PRAGMA index_list(), and # then matches them up. so same set of column_names in two # constraints will confuse it. Perhaps we should no longer # bother with index_list() here since we have the whole # CREATE TABLE? uniques = sorted( [ { "name": "UNIQUE_A", "column_names": ["A"] }, { "name": "UNIQUE_A_B_C", "column_names": ["A", "B", "C"] }, { "name": "UNIQUE_C_B_A", "column_names": ["C", "A", "B"] }, { "name": "UNIQUE_ASC_KEY", "column_names": ["ASC", "KEY"] }, { "name": "i.have.dots", "column_names": ["B"] }, { "name": "i have spaces", "column_names": ["C"] }, ], key=operator.itemgetter("name"), ) orig_meta = self.metadata table = Table( "testtbl", orig_meta, Column("A", sa.String(20)), Column("B", sa.String(30)), Column("C", sa.Integer), # reserved identifiers Column("ASC", sa.String(30)), Column("KEY", sa.String(30)), schema=schema, ) for uc in uniques: table.append_constraint( sa.UniqueConstraint(*uc["column_names"], name=uc["name"])) orig_meta.create_all() inspector = inspect(orig_meta.bind) reflected = sorted( inspector.get_unique_constraints("testtbl", schema=schema), key=operator.itemgetter("name"), ) names_that_duplicate_index = set() for orig, refl in zip(uniques, reflected): # Different dialects handle duplicate index and constraints # differently, so ignore this flag dupe = refl.pop("duplicates_index", None) if dupe: names_that_duplicate_index.add(dupe) eq_(orig, refl) reflected_metadata = MetaData() reflected = Table( "testtbl", reflected_metadata, autoload_with=orig_meta.bind, schema=schema, ) # test "deduplicates for index" logic. MySQL and Oracle # "unique constraints" are actually unique indexes (with possible # exception of a unique that is a dupe of another one in the case # of Oracle). make sure # they aren't duplicated. idx_names = set([idx.name for idx in reflected.indexes]) uq_names = set([ uq.name for uq in reflected.constraints if isinstance(uq, sa.UniqueConstraint) ]).difference(["unique_c_a_b"]) assert not idx_names.intersection(uq_names) if names_that_duplicate_index: eq_(names_that_duplicate_index, idx_names) eq_(uq_names, set())