Commit d6fbf129 authored by David Ripton's avatar David Ripton

Eradicate trailing whitespace

Remove all trailing spaces and tabs in every file in the project.
People have editors configured to do this, which causes them to
accidentally make little whitespace changes in unrelated commits,
which makes those commits harder to review.  Better to fix them all
at once.

Change-Id: I17d89f55f41d8599e0ab1a31f646cd161289703e
parent 21fcdad0
......@@ -130,9 +130,9 @@ Fixed bugs
- fixed case sensitivity in setup.py dependencies
- moved :py:mod:`migrate.changeset.exceptions` and
:py:mod:`migrate.versioning.exceptions` to :py:mod:`migrate.exceptions`
- cleared up test output and improved testing of deprecation warnings.
- cleared up test output and improved testing of deprecation warnings.
- some documentation fixes
- #107: fixed syntax error in genmodel.py
- #107: fixed syntax error in genmodel.py
- #96: fixed bug with column dropping in sqlite
- #94: fixed bug that prevented non-unique indexes being created
- fixed bug with column dropping involving foreign keys
......@@ -140,7 +140,7 @@ Fixed bugs
- rewrite of the schema diff internals, now supporting column
differences in additon to missing columns and tables.
- fixed bug when passing empty list in
:py:func:`migrate.versioning.shell.main` failed
:py:func:`migrate.versioning.shell.main` failed
- #108: Fixed issues with firebird support.
0.6 (11.07.2010)
......
......@@ -80,10 +80,10 @@ You can create a column with :meth:`~ChangesetColumn.create`:
You can pass `primary_key_name`, `index_name` and `unique_name` to the
:meth:`~ChangesetColumn.create` method to issue ``ALTER TABLE ADD
CONSTRAINT`` after changing the column.
CONSTRAINT`` after changing the column.
For multi columns constraints and other advanced configuration, check the
:ref:`constraint tutorial <constraint-tutorial>`.
:ref:`constraint tutorial <constraint-tutorial>`.
.. versionadded:: 0.6.0
......@@ -244,12 +244,12 @@ Foreign key constraints:
.. code-block:: python
from migrate.changeset.constraint import ForeignKeyConstraint
cons = ForeignKeyConstraint([table.c.fkey], [othertable.c.id])
# Create the constraint
cons.create()
# Drop the constraint
cons.drop()
......@@ -258,9 +258,9 @@ Check constraints:
.. code-block:: python
from migrate.changeset.constraint import CheckConstraint
cons = CheckConstraint('id > 3', columns=[table.c.id])
# Create the constraint
cons.create()
......@@ -272,7 +272,7 @@ Unique constraints:
.. code-block:: python
from migrate.changeset.constraint import UniqueConstraint
cons = UniqueConstraint('id', 'age', table=self.table)
# Create the constraint
......
FAQ
===
Q: Adding a **nullable=False** column
Q: Adding a **nullable=False** column
**************************************
A: Your table probably already contains data. That means if you add column, it's contents will be NULL.
......
......@@ -13,7 +13,7 @@ Automatically generating the code for this sort of task seems like a good soluti
* Maintence, usually a problem with auto-generated code, is not an issue: old database migration scripts are not the subject of maintenance; the correct solution is usually a new migration script.
Implementation is a problem: finding the 'diff' of two databases to determine what columns to add is not trivial. Fortunately, there exist tools that claim to do this for us: [http://sqlfairy.sourceforge.net/ SQL::Translator] and [http://xml2ddl.berlios.de/ XML to DDL] both claim to have this capability.
Implementation is a problem: finding the 'diff' of two databases to determine what columns to add is not trivial. Fortunately, there exist tools that claim to do this for us: [http://sqlfairy.sourceforge.net/ SQL::Translator] and [http://xml2ddl.berlios.de/ XML to DDL] both claim to have this capability.
...
......@@ -23,4 +23,4 @@ All that said, this is ''not'' something I'm going to attempt during the Summer
* The project has a deadline and I have plenty else to do already
* Lots of people with more experience than me say this would take more time than it's worth
It's something that might be considered for future work if this project is successful, though.
\ No newline at end of file
It's something that might be considered for future work if this project is successful, though.
\ No newline at end of file
......@@ -7,7 +7,7 @@ An option not discussed below is "no versioning"; that is, simply apply any scri
A single integer version number would specify the version of each database. This is stored in the database in a table, let's call it "schema"; each migration script is associated with a certain database version number.
+ Simple implementation[[br]]
Of the 3 solutions presented here, this one is by far the simplest.
Of the 3 solutions presented here, this one is by far the simplest.
+ Past success[[br]]
Used in [http://www.rubyonrails.org/ Ruby on Rails' migrations].
......@@ -32,13 +32,13 @@ Similar to the database-wide version number; the contents of the new table are m
- Determining the version of database-specific objects (ie. stored procedures, functions) is difficult.
- Ultimately gains nothing over the previous solution.[[br]]
The intent here was to allow multiple people to write scripts for a single database, but if database-wide version numbers aren't assigned until the script is placed in the repository, we could already do this.
The intent here was to allow multiple people to write scripts for a single database, but if database-wide version numbers aren't assigned until the script is placed in the repository, we could already do this.
=== Version determined via introspection ===
Each script has a schema associated with it, rather than a version number. The database schema is loaded, analyzed, and compared to the schema expected by the script.
Each script has a schema associated with it, rather than a version number. The database schema is loaded, analyzed, and compared to the schema expected by the script.
+ No modifications to the database are necessary for this versioning system.[[br]]
The primary advantage here is that no changes to the database are required.
The primary advantage here is that no changes to the database are required.
- Most difficult solution to implement, by far.[[br]]
Comparing the state of every schema object in the database is much more complex than simply comparing a version number, especially since we need to do it in a database-independent way (ie. we can't just diff the dump of each schema). SQLAlchemy's reflection would certainly be very helpful, but this remains the most complex solution.
......@@ -53,4 +53,4 @@ When version numbers are stored in the database, you have some idea of where an
----
'''Conclusion''': database-wide version numbers are the best way to go.
\ No newline at end of file
'''Conclusion''': database-wide version numbers are the best way to go.
\ No newline at end of file
This is very much a draft/brainstorm right now. It should be made prettier and thought about in more detail later, but it at least gives some idea of the direction we're headed right now.
This is very much a draft/brainstorm right now. It should be made prettier and thought about in more detail later, but it at least gives some idea of the direction we're headed right now.
----
* Two distinct tools; should not be coupled (can work independently):
* Versioning tool
......
== Goals ==
=== DBMS-independent schema changes ===
Many projects need to run on more than one DBMS. Similar changes need to be applied to both types of databases upon a schema change. The usual solution to database changes - .sql scripts with ALTER statements - runs into problems since different DBMSes have different dialects of SQL; we end up having to create a different script for each DBMS. This project will simplify this by providing an API, similar to the table definition API that already exists in SQLAlchemy, to alter a table independent of the DBMS being used, where possible.
Many projects need to run on more than one DBMS. Similar changes need to be applied to both types of databases upon a schema change. The usual solution to database changes - .sql scripts with ALTER statements - runs into problems since different DBMSes have different dialects of SQL; we end up having to create a different script for each DBMS. This project will simplify this by providing an API, similar to the table definition API that already exists in SQLAlchemy, to alter a table independent of the DBMS being used, where possible.
This project will support all DBMSes currently supported by SQLAlchemy: SQLite, Postgres, MySQL, Oracle, and MS SQL. Adding support for more should be as possible as it is in SQLAlchemy.
Many are already used to writing .sql scripts for database changes, aren't interested in learning a new API, and have projects where DBMS-independence isn't an issue. Writing SQL statements as part of a (Python) change script must be an option, of course. Writing change scripts as .sql scripts, eliminating Python scripts from the picture entirely, would be nice too, although this is a lower-priority goal.
Many are already used to writing .sql scripts for database changes, aren't interested in learning a new API, and have projects where DBMS-independence isn't an issue. Writing SQL statements as part of a (Python) change script must be an option, of course. Writing change scripts as .sql scripts, eliminating Python scripts from the picture entirely, would be nice too, although this is a lower-priority goal.
=== Database versioning and change script organization ===
Once we've accumulated a set of change scripts, it's important to know which ones have been applied/need to be applied to a particular database: suppose we need to upgrade a database that's extremenly out-of-date; figuring out the scripts to run by hand is tedious. Applying changes in the wrong order, or applying changes when they shouldn't be applied, is bad; attempting to manage all of this by hand inevitably leads to an accident. This project will be able to detect the version of a particular database and apply the scripts required to bring it up to the latest version, or up to any specified version number (given all change scripts required to reach that version number).
Once we've accumulated a set of change scripts, it's important to know which ones have been applied/need to be applied to a particular database: suppose we need to upgrade a database that's extremenly out-of-date; figuring out the scripts to run by hand is tedious. Applying changes in the wrong order, or applying changes when they shouldn't be applied, is bad; attempting to manage all of this by hand inevitably leads to an accident. This project will be able to detect the version of a particular database and apply the scripts required to bring it up to the latest version, or up to any specified version number (given all change scripts required to reach that version number).
Sometimes we need to be able to revert a schema to an older version. There's no automatic way to do this without rebuilding the database from scratch, so our project will allow one to write scripts to downgrade the database as well as upgrade it. If such scripts have been written, we should be able to apply them in the correct order, just like upgrading.
Sometimes we need to be able to revert a schema to an older version. There's no automatic way to do this without rebuilding the database from scratch, so our project will allow one to write scripts to downgrade the database as well as upgrade it. If such scripts have been written, we should be able to apply them in the correct order, just like upgrading.
Large projects inevitably accumulate a large number of database change scripts; it's important that we have a place to keep them. Once a script has been written, this project will deal with organizing it among existing change scripts, and the user will never have to look at it again.
Large projects inevitably accumulate a large number of database change scripts; it's important that we have a place to keep them. Once a script has been written, this project will deal with organizing it among existing change scripts, and the user will never have to look at it again.
=== Change testing ===
It's important to test one's database changes before applying them to a production database (unless you happen to like disasters). Much testing is up to the user and can't be automated, but there's a few places we can help ensure at least a minimal level of schema integrity. A few examples are below; we could add more later.
It's important to test one's database changes before applying them to a production database (unless you happen to like disasters). Much testing is up to the user and can't be automated, but there's a few places we can help ensure at least a minimal level of schema integrity. A few examples are below; we could add more later.
Given an obsolete schema, a database change script, and an up-to-date schema known to be correct, this project will be able to ensure that applying the
change script to the obsolete schema will result in an up-to-date schema - all without actually changing the obsolete database. Folks who have SQLAlchemy create their database using table.create() might find this useful; this is also useful for ensuring database downgrade scripts are correct.
change script to the obsolete schema will result in an up-to-date schema - all without actually changing the obsolete database. Folks who have SQLAlchemy create their database using table.create() might find this useful; this is also useful for ensuring database downgrade scripts are correct.
Given a schema of a known version and a complete set of change scripts up to that version, this project will be able to detect if the schema matches its version. If a schema has gone through changes not present in migration scripts, this test will fail; if applying all scripts in sequence up to the specified version creates an identical schema, this test will succeed. Identifying that a schema is corrupt is sufficient; it would be nice if we could give a clue as to what's wrong, but this is lower priority. (Implementation: we'll probably show a diff of two schema dumps; this should be enough to tell the user what's gone wrong.)
Given a schema of a known version and a complete set of change scripts up to that version, this project will be able to detect if the schema matches its version. If a schema has gone through changes not present in migration scripts, this test will fail; if applying all scripts in sequence up to the specified version creates an identical schema, this test will succeed. Identifying that a schema is corrupt is sufficient; it would be nice if we could give a clue as to what's wrong, but this is lower priority. (Implementation: we'll probably show a diff of two schema dumps; this should be enough to tell the user what's gone wrong.)
== Non-Goals ==
ie. things we will '''not''' try to do (at least, during the Summer of Code)
=== Automatic generation of schema changes ===
For example, one might define a table:
For example, one might define a table:
{{{
CREATE TABLE person (
id integer,
......
......@@ -69,5 +69,5 @@ One recurring problem I've had with this project is dealing with changes to the
I'm now working on another project that will be making use of SQLAlchemy: it fits many of my project's requirements, but lacks a migration tool that will be much needed. This presents an opportunity for me to make my first contribution to open source - I've long been interested in open source software and use it regularly, but haven't contributed to any until now. I'm particularly interested in the application of this tool with the TurboGears framework, as this project was inspired by a suggestion the TurboGears mailing list and I'm working on a project using TurboGears - but there is no reason to couple an SQLAlchemy enhancement with TurboGears; this project may be used by anyone who uses SQLAlchemy.
Further information:
Further information:
http://evan.zealgame.com/soc
......@@ -2,11 +2,11 @@ This plan has several problems and has been modified; new plan is discussed in w
----
One problem with [http://www.rubyonrails.org/ Ruby on Rails'] (very good) schema migration system is the behavior of scripts that depend on outside sources; ie. the application. If those change, there's no guarantee that such scripts will behave as they did before, and you'll get strange results.
One problem with [http://www.rubyonrails.org/ Ruby on Rails'] (very good) schema migration system is the behavior of scripts that depend on outside sources; ie. the application. If those change, there's no guarantee that such scripts will behave as they did before, and you'll get strange results.
For example, suppose one defines a SQLAlchemy table:
{{{
users = Table('users', metadata,
users = Table('users', metadata,
Column('user_id', Integer, primary_key = True),
Column('user_name', String(16), nullable = False),
Column('password', String(20), nullable = False)
......@@ -30,7 +30,7 @@ def upgrade():
}}}
...and change our application's table definition:
{{{
users = Table('users', metadata,
users = Table('users', metadata,
Column('user_id', Integer, primary_key = True),
Column('user_name', String(16), nullable = False),
Column('password', String(20), nullable = False),
......
My original plan for Migrate's RepositoryFormat had several problems:
* Bind parameters: We needed to bind parameters into statements to get something suitable for an .sql file. For some types of parameters, there's no clean way to do this without writing an entire parser - too great a cost for this project. There's a reason why SQLAlchemy's logs display the statement and its parameters separately: the binding is done at a lower level than we have access to.
* Bind parameters: We needed to bind parameters into statements to get something suitable for an .sql file. For some types of parameters, there's no clean way to do this without writing an entire parser - too great a cost for this project. There's a reason why SQLAlchemy's logs display the statement and its parameters separately: the binding is done at a lower level than we have access to.
* Failure: Discussed in #17, the old format had no easy way to find the Python statements associated with an SQL error. This makes it difficult to debug scripts.
A new format will be used to solve this problem instead.
......@@ -15,9 +15,9 @@ These files will contain the following information:
* Parameters to be bound to the statement
* A Python stack trace at the point the statement was logged - this allows us to tell what Python statements are associated with an SQL statement when there's an error
These files will be created by pickling a Python object with the above information.
These files will be created by pickling a Python object with the above information.
Such files may be executed by loading the log and having SQLAlchemy execute them as it might have before.
Such files may be executed by loading the log and having SQLAlchemy execute them as it might have before.
Good:
* Since the statements and bind parameters are stored separately and executed as SQLAlchemy would normally execute them, one problem discussed above is eliminated.
......
......@@ -165,7 +165,7 @@ SQLAlchemy Migrate is split into two parts, database schema versioning
API Documentation
------------------
------------------
.. toctree::
......
......@@ -33,7 +33,7 @@ body {
#content p,
#content ul,
#content blockquote {
#content blockquote {
line-height: 1.6em;
}
......@@ -55,7 +55,7 @@ h1, h2, h3 {
margin-bottom: .7em;
}
h1 {
h1 {
font-size: 2.5em;
}
h2 {
......@@ -73,9 +73,9 @@ h1 a, h2 a, h3 a {
color: #33a;
}
h1, h1 a, h1 a:hover, h1 a:visited,
h2, h2 a, h2 a:hover, h2 a:visited,
h3, h3 a, h3 a:hover, h3 a:visited,
h1, h1 a, h1 a:hover, h1 a:visited,
h2, h2 a, h2 a:hover, h2 a:visited,
h3, h3 a, h3 a:hover, h3 a:visited,
cite {
text-decoration: none;
}
......@@ -113,12 +113,12 @@ a:hover {
}
/* Special case doc-title */
h1.doc-title {
h1.doc-title {
text-transform: lowercase;
font-size: 4em;
margin: 0;
}
h1.doc-title a {
h1.doc-title a {
display: block;
padding-left: 0.8em;
padding-bottom: .5em;
......@@ -126,8 +126,8 @@ h1.doc-title a {
margin: 0;
border-bottom: 1px #fff solid;
}
h1.doc-title,
h1.doc-title a,
h1.doc-title,
h1.doc-title a,
h1.doc-title a:visited,
h1.doc-title a:hover {
text-decoration: none;
......@@ -149,7 +149,7 @@ body {
max-width: 60em;
border: 1px solid #555596;
}
* html #page {
* html #page {
* width: 60em;
* }
*
......@@ -157,7 +157,7 @@ body {
* margin: 0 1em 0 3em;
* }
*
* #content h1 {
* #content h1 {
* margin-left: 0;
* }
*
......
......@@ -4,10 +4,10 @@
/* Basic Style
----------------------------------- */
h1.pudge-member-page-heading {
h1.pudge-member-page-heading {
font-size: 300%;
}
h4.pudge-member-page-subheading {
h4.pudge-member-page-subheading {
font-size: 130%;
font-style: italic;
margin-top: -2.0em;
......@@ -15,24 +15,24 @@ h4.pudge-member-page-subheading {
margin-bottom: .3em;
color: #0050CC;
}
p.pudge-member-blurb {
p.pudge-member-blurb {
font-style: italic;
font-weight: bold;
font-size: 120%;
margin-top: 0.2em;
color: #999;
}
p.pudge-member-parent-link {
p.pudge-member-parent-link {
margin-top: 0;
}
/*div.pudge-module-doc {
/*div.pudge-module-doc {
max-width: 45em;
}*/
div.pudge-section {
div.pudge-section {
margin-left: 2em;
max-width: 45em;
}
/* Section Navigation
/* Section Navigation
----------------------------------- */
div#pudge-section-nav
......@@ -42,7 +42,7 @@ div#pudge-section-nav
height: 20px;
}
div#pudge-section-nav ul {
div#pudge-section-nav ul {
border: 0;
margin: 0;
padding: 0;
......@@ -90,33 +90,33 @@ div#pudge-section-nav ul li .pudge-section-link {
/* Module Lists
----------------------------------- */
dl.pudge-module-list dt {
dl.pudge-module-list dt {
font-style: normal;
font-size: 110%;
}
dl.pudge-module-list dd {
dl.pudge-module-list dd {
color: #555;
}
/* Misc Overrides */
.rst-doc p.topic-title a {
.rst-doc p.topic-title a {
color: #777;
}
.rst-doc ul.auto-toc a,
.rst-doc div.contents a {
.rst-doc div.contents a {
color: #333;
}
pre { background: #eee; }
.rst-doc dl dt {
.rst-doc dl dt {
color: #444;
margin-top: 1em;
font-weight: bold;
}
.rst-doc dl dd {
.rst-doc dl dd {
margin-top: .2em;
}
.rst-doc hr {
.rst-doc hr {
display: block;
margin: 2em 0;
}
......
......@@ -75,7 +75,7 @@ script applied to the database increments this version number. You can retrieve
a database's current :term:`version`::
$ python my_repository/manage.py db_version sqlite:///project.db my_repository
0
0
A freshly versioned database begins at version 0 by default. This assumes the
database is empty or does only contain schema elements (tables, views,
......@@ -172,7 +172,7 @@ Our change script predefines two functions, currently empty:
Column('login', String(40)),
Column('passwd', String(40)),
)
def upgrade(migrate_engine):
meta.bind = migrate_engine
......@@ -251,9 +251,9 @@ Our :term:`repository's <repository>` :term:`version` is::
The :option:`test` command executes actual scripts, be sure you are *NOT*
doing this on production database.
If you need to test production changes you should:
#. get a dump of your production database
#. import the dump into an empty database
#. run :option:`test` or :option:`upgrade` on that copy
......@@ -363,7 +363,7 @@ your application - the same SQL should be generated every time, despite any
changes to your app's source code. You don't want your change scripts' behavior
changing when your source code does.
.. warning::
.. warning::
**Consider the following example of what NOT to do**
......@@ -372,7 +372,7 @@ changing when your source code does.
.. code-block:: python
from sqlalchemy import *
meta = MetaData()
table = Table('mytable', meta,
Column('id', Integer, primary_key=True),
......@@ -381,7 +381,7 @@ changing when your source code does.
... and uses this file to create a table in a change script:
.. code-block:: python
from sqlalchemy import *
from migrate import *
import model
......@@ -390,7 +390,7 @@ changing when your source code does.
model.meta.bind = migrate_engine
def downgrade(migrate_engine):
model.meta.bind = migrate_engine
model.meta.bind = migrate_engine
model.table.drop()
This runs successfully the first time. But what happens if we change the
......@@ -399,7 +399,7 @@ changing when your source code does.
.. code-block:: python
from sqlalchemy import *
meta = MetaData()
table = Table('mytable', meta,
Column('id', Integer, primary_key=True),
......@@ -448,7 +448,7 @@ database. Use engine.name to get the name of the database you're working with
>>> from sqlalchemy import *
>>> from migrate import *
>>>
>>>
>>> engine = create_engine('sqlite:///:memory:')
>>> engine.name
'sqlite'
......@@ -537,7 +537,7 @@ function names match equivalent shell commands. You can use this to
help integrate SQLAlchemy Migrate with your existing update process.
For example, the following commands are similar:
*From the command line*::
$ migrate help help
......@@ -553,9 +553,9 @@ For example, the following commands are similar:
migrate.versioning.api.help('help')
# Output:
# %prog help COMMAND
#
#
# Displays help on a given command.
.. _migrate.versioning.api: module-migrate.versioning.api.html
......@@ -631,7 +631,7 @@ One may also want to specify custom themes. API functions accept
``templates_theme`` for this purpose (which defaults to `default`)
Example::
/home/user/templates/manage $ ls
default.py_tmpl
pylons.py_tmpl
......
......@@ -56,7 +56,7 @@ class AlterTableVisitor(SchemaVisitor):
# adapt to 0.6 which uses a string-returning
# object
self.append(" %s" % ret)
def _to_table(self, param):
"""Returns the table object for the given param object."""
if isinstance(param, (sa.Column, sa.Index, sa.schema.Constraint)):
......@@ -113,7 +113,7 @@ class ANSIColumnGenerator(AlterTableVisitor, SchemaGenerator):
# SA bounds FK constraints to table, add manually
for fk in column.foreign_keys:
self.add_foreignkey(fk.constraint)
# add primary key constraint if needed
if column.primary_key_name:
cons = constraint.PrimaryKeyConstraint(column,
......
......@@ -31,7 +31,7 @@ class FBColumnDropper(ansisql.ANSIColumnDropper):
if column.name in [col.name for col in index.columns]:
index.drop()
# TODO: recreate index if it references more than this column
for cons in column.table.constraints:
if isinstance(cons,PrimaryKeyConstraint):
# will be deleted only when the column its on
......
......@@ -42,7 +42,7 @@ class SQLiteHelper(SQLiteCommon):
self.execute()
self.append('DROP TABLE migration_tmp')
self.execute()
def visit_column(self, delta):
if isinstance(delta, DictMixin):
column = delta.result_column
......@@ -52,7 +52,7 @@ class SQLiteHelper(SQLiteCommon):
table = self._to_table(column.table)
self.recreate_table(table,column,delta)
class SQLiteColumnGenerator(SQLiteSchemaGenerator,
class SQLiteColumnGenerator(SQLiteSchemaGenerator,
ansisql.ANSIColumnGenerator,
# at the end so we get the normal
# visit_column by default
......@@ -78,7 +78,7 @@ class SQLiteColumnDropper(SQLiteHelper, ansisql.ANSIColumnDropper):
"""SQLite ColumnDropper"""
def _modify_table(self, table, column, delta):
columns = ' ,'.join(map(self.preparer.format_column, table.columns))
return 'INSERT INTO %(table_name)s SELECT ' + columns + \
' from migration_tmp'
......
......@@ -31,7 +31,7 @@ __all__ = [
def create_column(column, table=None, *p, **kw):
"""Create a column, given the table.
API to :meth:`ChangesetColumn.create`.
"""
if table is not None:
......@@ -41,7 +41,7 @@ def create_column(column, table=None, *p, **kw):
def drop_column(column, table=None, *p, **kw):
"""Drop a column, given the table.
API to :meth:`ChangesetColumn.drop`.
"""
if table is not None:
......@@ -105,12 +105,12 @@ def alter_column(*p, **k):
:param engine:
The :class:`~sqlalchemy.engine.base.Engine` to use for table
reflection and schema alterations.
:returns: A :class:`ColumnDelta` instance representing the change.
"""
if 'table' not in k and isinstance(p[0], sqlalchemy.Column):
k['table'] = p[0].table
if 'engine' not in k:
......@@ -129,7 +129,7 @@ def alter_column(*p, **k):
# that this crutch has to be left in until they can be sorted
# out
k['alter_metadata']=True
delta = ColumnDelta(*p, **k)
visitorcallable = get_engine_visitor(engine, 'schemachanger')
......@@ -183,10 +183,10 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
:param table: Table at which current Column should be bound to.\
If table name is given, reflection will be used.
:type table: string or Table instance
:param metadata: A :class:`MetaData` instance to store
reflected table names
:param engine: When reflecting tables, either engine or metadata must \
be specified to acquire engine object.
:type engine: :class:`Engine` instance
......@@ -211,7 +211,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
# as a crutch until the tests that fail when 'alter_metadata'
# behaviour always happens can be sorted out
self.alter_metadata = kw.pop("alter_metadata", False)
self.meta = kw.pop("metadata", None)
self.engine = kw.pop("engine", None)
......@@ -239,7 +239,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
self.alter_metadata,
super(ColumnDelta, self).__repr__()
)
def __getitem__(self, key):
if key not in self.keys():
raise KeyError("No such diff key, available: %s" % self.diffs )
......@@ -278,7 +278,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem):
"""Compares two Column objects"""
self.process_column(new_col)
self.table = k.pop('table', None)
# we cannot use bool() on table in SA06
# we cannot use bool() on table in SA06
if self.table is None:
self.table = old_col.table
if self.table is None:
......@@ -482,7 +482,7 @@ class ChangesetColumn(object):
def alter(self, *p, **k):
"""Makes a call to :func:`alter_column` for the column this
method is called on.
method is called on.
"""
if 'table' not in k:
k['table'] = self.table
......@@ -560,12 +560,12 @@ populated with defaults
def _col_name_in_constraint(self,cons,name):
return False
def remove_from_table(self, table, unset_table=True):
# TODO: remove primary keys, constraints, etc
if unset_table:
self.table = None
to_drop = set()
for index in table.indexes:
columns = []
......@@ -579,7 +579,7 @@ populated with defaults
else:
to_drop.add(index)
table.indexes = table.indexes - to_drop
to_drop = set()
for cons in table.constraints:
# TODO: deal with other types of constraint
......@@ -591,7 +591,7 @@ populated with defaults
if self.name==col_name:
to_drop.add(cons)
table.constraints = table.constraints - to_drop
if table.c.contains_column(self):
if SQLA_07:
table._columns.remove(self)
......
......@@ -65,7 +65,7 @@ class TestAddDropColumn(fixture.DB):
result = len(self.table.primary_key)
self.assertEqual(result, num_of_expected_cols)
# we have 1 columns and there is no data column
# we have 1 columns and there is no data column
assert_numcols(1)
self.assertTrue(getattr(self.table.c, 'data', None) is None)
if len(col_p) == 0:
......@@ -147,7 +147,7 @@ class TestAddDropColumn(fixture.DB):
# Not necessarily bound to table
return self.table.drop_column(col.name)
return self.run_(add_func, drop_func)
@fixture.usedb()
def test_byname(self):
"""Add/drop columns via functions; by table object and column name"""
......@@ -302,7 +302,7 @@ class TestAddDropColumn(fixture.DB):
if index.name=='ix_data':
break
self.assertEqual(expected,index.unique)
@fixture.usedb()
def test_index(self):
col = Column('data', Integer)
......@@ -311,7 +311,7 @@ class TestAddDropColumn(fixture.DB):
self._check_index(False)
col.drop()
@fixture.usedb()
def test_index_unique(self):
# shows how to create a unique index
......@@ -332,7 +332,7 @@ class TestAddDropColumn(fixture.DB):
self._check_index(True)
col.drop()
@fixture.usedb()
def test_server_defaults(self):
"""Can create columns with server_default values"""
......@@ -382,7 +382,7 @@ class TestAddDropColumn(fixture.DB):
sorted([i.name for i in self.table.indexes]),
[u'ix_tmp_adddropcol_d1', u'ix_tmp_adddropcol_d2']
)
# delete one
self.table.c.d2.drop()
......@@ -392,7 +392,7 @@ class TestAddDropColumn(fixture.DB):
sorted([i.name for i in self.table.indexes]),
[u'ix_tmp_adddropcol_d1']
)