Hi there!

I'm looking to create a helper or decorator function that will enable us to 
"mark" a column or table as “unused”, and raise an error if that column or 
table is queried for in SQL.


Context
The motivation behind this is to help us catch accidental references to 
deleted columns in our code. We currently follow this process for database 
migrations that involve dropping columns or tables:

   1. Remove all usages of the column in the code, except the column 
   definition. (We keep the column definition around since we have tests to 
   ensure our column definitions match up with our migrated database schemas.)
   2. Make the column deferred
   3. Wait a few days, then remove the column definition and run the 
   database migration that actually drops the column 

The main issue with this process is that if there’s any code left in that 
loads in the deleted column, we run into a number of issues upon running 
the migration. We’d like to introduce a helper or decorator for dropped 
columns/tables that will trigger an error when the column/table is 
referenced / loaded in any of the following ways:

   1. session.query(MyTable.my_column).all()
   2. session.query(MyTable).options(undefer('*')).all()
   3. my_table_instance.my_column
   4. session.query(MyDroppedTable).all()
   
Ideally, this would be a lightweight wrapper or decorator that could be 
applied to any column or table — something like my_column = 
unused(Column(…)) or an @unused decorator on a class.


Prior Work
We’ve looked at using hybrid_property to achieve this:


class MyTable():
    ...
    _my_column = deferred(Column('my_column', String(255), nullable=True))
    
    @hybrid_property
    def my_column(self):
        raise Exception('Unused column')
    
    @my_column.setter
    def my_column(self, value):
        raise Exception('Unused column')


What this gets us:

   - Exception on my_table_instance.my_column
   - Exception on session.query(MyTable.my_column).all()
   - Exception on session.query(MyTable).options(undefer('my_column')).all()

Issues with this approach:

   1. No exception on session.query(MyTable).options(undefer('*')).all()
   2. Requires a fair amount of implementation overhead for each column
   3. Not applicable to unused tables



Any tips on how we can best use SQLAlchemy to accomplish all of the above?


Thank you!
Neena

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to