From: Mike Bayer Date: Sat, 1 May 2010 22:42:37 +0000 (-0400) Subject: create table construct, does the "metadata" thing as well. X-Git-Tag: rel_0_1_0~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e97a6c3fceb36a1d71bf477c87a92fc2f1fcc5c5;p=thirdparty%2Fsqlalchemy%2Falembic.git create table construct, does the "metadata" thing as well. --- diff --git a/alembic/context.py b/alembic/context.py index 176388bd..6978bbaa 100644 --- a/alembic/context.py +++ b/alembic/context.py @@ -1,4 +1,3 @@ -from alembic.ddl import base from alembic import util from sqlalchemy import MetaData, Table, Column, String, literal_column, text from sqlalchemy.schema import CreateTable @@ -110,6 +109,7 @@ def opts(cfg, **kw): def configure_connection(connection): global _context + from alembic.ddl import base _context = _context_impls.get(connection.dialect.name, DefaultContext)(connection, **_context_opts) def run_migrations(**kw): diff --git a/alembic/ddl/__init__.py b/alembic/ddl/__init__.py index 20bb6d77..07b063dd 100644 --- a/alembic/ddl/__init__.py +++ b/alembic/ddl/__init__.py @@ -1 +1 @@ -import base, postgresql, mysql, sqlite \ No newline at end of file +import postgresql, mysql, sqlite \ No newline at end of file diff --git a/alembic/op.py b/alembic/op.py index dbd0de4e..d2b1083d 100644 --- a/alembic/op.py +++ b/alembic/op.py @@ -38,13 +38,42 @@ def _foreign_key_constraint(name, source, referent, local_cols, remote_cols): name=name ) t1.append_constraint(f) + return f def _unique_constraint(name, source, local_cols): t = schema.Table(source, schema.MetaData(), *[schema.Column(n, NULLTYPE) for n in local_cols]) return schema.UniqueConstraint(*t.c, name=name) + +def _table(name, *columns, **kw): + m = schema.MetaData() + t = schema.Table(name, m, *columns, **kw) + for f in t._foreign_keys: + _ensure_table_for_fk(m, f) + return t + +def _ensure_table_for_fk(metadata, fk): + """create a placeholder Table object for the referent of a + ForeignKey. + """ + if isinstance(fk._colspec, basestring): + table_key, cname = fk._colspec.split('.') + if '.' in table_key: + tokens = tname.split('.') + sname = ".".join(tokens[0:-1]) + tname = tokens[-1] + else: + tname = table_key + sname = None + if table_key not in metadata.tables: + rel_t = schema.Table(tname, metadata, schema=sname) + else: + rel_t = metadata.tables[table_key] + if not rel_t.c.contains_column(cname): + rel_t.append_column(schema.Column(cname, NULLTYPE)) + def create_foreign_key(name, source, referent, local_cols, remote_cols): get_context().add_constraint( _foreign_key_constraint(source, referent, local_cols, remote_cols) @@ -55,5 +84,10 @@ def create_unique_constraint(name, source, local_cols): _unique_constraint(name, source, local_cols) ) +def create_table(name, *columns, **kw): + get_context().create_table( + _table(name, *columns, **kw) + ) + def execute(sql): get_context().execute(sql) \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py index 5b33b994..64ebcb5e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -18,7 +18,10 @@ def _get_dialect(name): def assert_compiled(element, assert_string, dialect=None): dialect = _get_dialect(dialect) - eq_(unicode(element.compile(dialect=dialect)), assert_string) + eq_( + unicode(element.compile(dialect=dialect)).replace("\n", "").replace("\t", ""), + assert_string.replace("\n", "").replace("\t", "") + ) def _testing_config(): from alembic.config import Config diff --git a/tests/test_schema.py b/tests/test_schema.py index 5ba4fc9e..84bff84d 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -1,6 +1,9 @@ from tests import assert_compiled from alembic import op -from sqlalchemy.schema import AddConstraint, ForeignKeyConstraint +from sqlalchemy.schema import AddConstraint, ForeignKeyConstraint, \ + CreateTable, Column, ForeignKey,\ + MetaData, Table +from sqlalchemy import Integer def test_foreign_key(): fk = op._foreign_key_constraint('fk_test', 't1', 't2', ['foo', 'bar'], ['bat', 'hoho']) @@ -15,4 +18,50 @@ def test_unique_constraint(): AddConstraint(uc), "ALTER TABLE t1 ADD CONSTRAINT uk_test UNIQUE (foo, bar)" ) - \ No newline at end of file + + +def test_table(): + tb = op._table("some_table", + Column('id', Integer, primary_key=True), + Column('foo_id', Integer, ForeignKey('foo.id')), + schema='schema' + ) + assert_compiled( + CreateTable(tb), + "CREATE TABLE schema.some_table (" + "id INTEGER NOT NULL, " + "foo_id INTEGER, " + "PRIMARY KEY (id), " + "FOREIGN KEY(foo_id) REFERENCES foo (id))" + ) + + tb = op._table("some_table", + Column('id', Integer, primary_key=True), + Column('foo_id', Integer, ForeignKey('foo.id')), + Column('foo_bar', Integer, ForeignKey('foo.bar')), + ) + assert_compiled( + CreateTable(tb), + "CREATE TABLE some_table (" + "id INTEGER NOT NULL, " + "foo_id INTEGER, " + "foo_bar INTEGER, " + "PRIMARY KEY (id), " + "FOREIGN KEY(foo_id) REFERENCES foo (id), " + "FOREIGN KEY(foo_bar) REFERENCES foo (bar))" + ) + + m = MetaData() + foo = Table('foo', m, Column('id', Integer, primary_key=True)) + tb = op._table("some_table", + Column('id', Integer, primary_key=True), + Column('foo_id', Integer, ForeignKey('foo.id')), + ) + assert_compiled( + CreateTable(tb), + "CREATE TABLE some_table (" + "id INTEGER NOT NULL, " + "foo_id INTEGER, " + "PRIMARY KEY (id), " + "FOREIGN KEY(foo_id) REFERENCES foo (id))" + ) \ No newline at end of file