lipstick changes

This commit is contained in:
iElectric 2009-06-10 14:00:53 +00:00
parent 75494ae226
commit 15cb31cea6
7 changed files with 107 additions and 103 deletions

View File

@ -25,14 +25,14 @@ Column
Given a standard SQLAlchemy table::
table = Table('mytable',meta,
Column('id',Integer,primary_key=True),
table = Table('mytable', meta,
Column('id', Integer, primary_key=True),
)
table.create()
Create a column::
col = Column('col1',String)
col = Column('col1', String)
col.create(table)
# Column is added to table based on its name
@ -92,7 +92,7 @@ SQLAlchemy supports creating/dropping constraints at the same time a table is cr
Primary key constraints::
cons = PrimaryKeyConstraint(col1,col2)
cons = PrimaryKeyConstraint(col1, col2)
# Create the constraint
cons.create()
# Drop the constraint
@ -100,7 +100,7 @@ Primary key constraints::
Note that Oracle requires that you state the name of the primary key constraint to be created/dropped. SQLAlchemy Migrate will try to guess the name of the PK constraint for other databases, but if it's something other than the default, you'll need to give its name::
PrimaryKeyConstraint(col1,col2,name='my_pk_constraint')
PrimaryKeyConstraint(col1, col2, name='my_pk_constraint')
Foreign key constraints::
@ -112,4 +112,4 @@ Foreign key constraints::
Names are specified just as with primary key constraints::
ForeignKeyConstraint([table.c.fkey], [othertable.c.id],name='my_fk_constraint')
ForeignKeyConstraint([table.c.fkey], [othertable.c.id], name='my_fk_constraint')

View File

@ -33,7 +33,7 @@ class RawAlterTableVisitor(object):
def _do_quote_table_identifier(self, identifier):
"""Returns a quoted version of the given table identifier."""
return '"%s"'%identifier
return '"%s"' % identifier
def start_alter_table(self, param):
"""Returns the start of an ``ALTER TABLE`` SQL-Statement.

View File

@ -106,9 +106,7 @@ class PrimaryKeyConstraint(ConstraintChangeset, schema.PrimaryKeyConstraint):
def autoname(self):
"""Mimic the database's automatic constraint names"""
ret = "%(table)s_pkey"%dict(
table=self.table.name,
)
ret = "%(table)s_pkey" % dict(table=self.table.name)
return ret
def drop(self, *args, **kwargs):

View File

@ -2,7 +2,9 @@
Schema module providing common schema operations.
"""
import re
import sqlalchemy
from migrate.changeset.databases.visitor import get_engine_visitor
__all__ = [
@ -15,37 +17,19 @@ __all__ = [
def create_column(column, table=None, *p, **k):
"""Create a column, given the table"""
if table is not None:
return table.create_column(column, *p, **k)
return column.create(*p, **k)
def drop_column(column, table=None, *p, **k):
"""Drop a column, given the table"""
if table is not None:
return table.drop_column(column, *p, **k)
return column.drop(*p, **k)
def _to_table(table, engine=None):
if isinstance(table, sqlalchemy.Table):
return table
# Given: table name, maybe an engine
meta = sqlalchemy.MetaData()
if engine is not None:
meta.bind = engine
return sqlalchemy.Table(table, meta)
def _to_index(index, table=None, engine=None):
if isinstance(index, sqlalchemy.Index):
return index
# Given: index name; table name required
table = _to_table(table, engine)
ret = sqlalchemy.Index(index)
ret.table = table
return ret
def rename_table(table, name, engine=None):
"""Rename a table, given the table's current name and the new
name."""
@ -63,16 +47,6 @@ def rename_index(index, name, table=None, engine=None):
index = _to_index(index, table, engine)
index.rename(name)
def _engine_run_visitor(engine, visitorcallable, element, **kwargs):
conn = engine.connect()
try:
element.accept_schema_visitor(visitorcallable(engine.dialect,
connection=conn))
finally:
conn.close()
def alter_column(*p, **k):
"""Alter a column.
@ -114,6 +88,35 @@ def alter_column(*p, **k):
setattr(col, key, val)
def _to_table(table, engine=None):
if isinstance(table, sqlalchemy.Table):
return table
# Given: table name, maybe an engine
meta = sqlalchemy.MetaData()
if engine is not None:
meta.bind = engine
return sqlalchemy.Table(table, meta)
def _to_index(index, table=None, engine=None):
if isinstance(index, sqlalchemy.Index):
return index
# Given: index name; table name required
table = _to_table(table, engine)
ret = sqlalchemy.Index(index)
ret.table = table
return ret
def _engine_run_visitor(engine, visitorcallable, element, **kwargs):
conn = engine.connect()
try:
element.accept_schema_visitor(visitorcallable(engine.dialect,
connection=conn))
finally:
conn.close()
def _normalize_table(column, table):
if table is not None:
if table is not column.table:

View File

@ -87,7 +87,7 @@ def create(repository, name, **opts):
@catch_known_errors
def script(description, repository, **opts):
"""%prog script [--repository=REPOSITORY_PATH] DESCRIPTION
"""%prog script DESCRIPTION REPOSITORY_PATH
Create an empty change script using the next unused version number
appended with the given description.
@ -101,7 +101,7 @@ def script(description, repository, **opts):
@catch_known_errors
def script_sql(database, repository, **opts):
"""%prog script_sql [--repository=REPOSITORY_PATH] DATABASE
"""%prog script_sql DATABASE REPOSITORY_PATH
Create empty change SQL scripts for given DATABASE, where DATABASE
is either specific ('postgres', 'mysql', 'oracle', 'sqlite', etc.)
@ -115,29 +115,6 @@ def script_sql(database, repository, **opts):
repo.create_script_sql(database, **opts)
def test(repository, url=None, **opts):
"""%prog test REPOSITORY_PATH URL [VERSION]
Performs the upgrade and downgrade option on the given
database. This is not a real test and may leave the database in a
bad state. You should therefore better run the test on a copy of
your database.
"""
engine = construct_engine(url, **opts)
repos = Repository(repository)
script = repos.version(None).script()
# Upgrade
print "Upgrading...",
script.run(engine, 1)
print "done"
print "Downgrading...",
script.run(engine, -1)
print "done"
print "Success"
def version(repository, **opts):
"""%prog version REPOSITORY_PATH
@ -147,6 +124,20 @@ def version(repository, **opts):
return repo.latest
def db_version(url, repository, **opts):
"""%prog db_version URL REPOSITORY_PATH
Show the current version of the repository with the given
connection string, under version control of the specified
repository.
The url should be any valid SQLAlchemy connection string.
"""
engine = construct_engine(url, **opts)
schema = ControlledSchema(engine, repository)
return schema.version
def source(version, dest=None, repository=None, **opts):
"""%prog source VERSION [DESTINATION] --repository=REPOSITORY_PATH
@ -166,43 +157,6 @@ def source(version, dest=None, repository=None, **opts):
return ret
def version_control(url, repository, version=None, **opts):
"""%prog version_control URL REPOSITORY_PATH [VERSION]
Mark a database as under this repository's version control.
Once a database is under version control, schema changes should
only be done via change scripts in this repository.
This creates the table version_table in the database.
The url should be any valid SQLAlchemy connection string.
By default, the database begins at version 0 and is assumed to be
empty. If the database is not empty, you may specify a version at
which to begin instead. No attempt is made to verify this
version's correctness - the database schema is expected to be
identical to what it would be if the database were created from
scratch.
"""
engine = construct_engine(url, **opts)
ControlledSchema.create(engine, repository, version)
def db_version(url, repository, **opts):
"""%prog db_version URL REPOSITORY_PATH
Show the current version of the repository with the given
connection string, under version control of the specified
repository.
The url should be any valid SQLAlchemy connection string.
"""
engine = construct_engine(url, **opts)
schema = ControlledSchema(engine, repository)
return schema.version
def upgrade(url, repository, version=None, **opts):
"""%prog upgrade URL REPOSITORY_PATH [VERSION] [--preview_py|--preview_sql]
@ -236,6 +190,51 @@ def downgrade(url, repository, version, **opts):
"Try 'upgrade' instead."
return _migrate(url, repository, version, upgrade=False, err=err, **opts)
def test(repository, url, **opts):
"""%prog test REPOSITORY_PATH URL [VERSION]
Performs the upgrade and downgrade option on the given
database. This is not a real test and may leave the database in a
bad state. You should therefore better run the test on a copy of
your database.
"""
engine = construct_engine(url, **opts)
repos = Repository(repository)
script = repos.version(None).script()
# Upgrade
print "Upgrading...",
script.run(engine, 1)
print "done"
print "Downgrading...",
script.run(engine, -1)
print "done"
print "Success"
def version_control(url, repository, version=None, **opts):
"""%prog version_control URL REPOSITORY_PATH [VERSION]
Mark a database as under this repository's version control.
Once a database is under version control, schema changes should
only be done via change scripts in this repository.
This creates the table version_table in the database.
The url should be any valid SQLAlchemy connection string.
By default, the database begins at version 0 and is assumed to be
empty. If the database is not empty, you may specify a version at
which to begin instead. No attempt is made to verify this
version's correctness - the database schema is expected to be
identical to what it would be if the database were created from
scratch.
"""
engine = construct_engine(url, **opts)
ControlledSchema.create(engine, repository, version)
def drop_version_control(url, repository, **opts):
"""%prog drop_version_control URL REPOSITORY_PATH
@ -279,7 +278,7 @@ def compare_model_to_db(url, model, repository, **opts):
def create_model(url, repository, **opts):
"""%prog create_model URL REPOSITORY_PATH
"""%prog create_model URL REPOSITORY_PATH [DECLERATIVE=True]
Dump the current database as a Python model to stdout.

View File

@ -11,6 +11,7 @@ from migrate.versioning.template import template
from migrate.versioning.script import base
from migrate.versioning.util import import_path, load_model, construct_engine
class PythonScript(base.BaseScript):
"""Base for Python scripts"""

View File

@ -151,6 +151,9 @@ class TestControlledSchema(fixture.Pathed, fixture.DB):
dbschema.upgrade(10)
self.assertRaises(ValueError, dbschema.upgrade, 'a')
self.assertRaises(exceptions.InvalidVersionError, dbschema.runchange, 20, '', 1)
# TODO: test for table version in db
# cleanup