Hi, I'm fairly new to sqlalchemy and I noticed that I've written some utility
functions which I seek advice upon (acting on the assumption that they're
fairly silly and somebody must just enlighten my ways :D).

Thanks for having a look at the atachment,
Florian
# The following two functions help me define a mapper
# which I couldn't do otherwise (due to inheritance)
def find_fk_column(table, parent_table):
    for column in parent_table.columns:
        foreign_key = column.foreign_key
        if foreign_key:
            if foreign_key.column.table == table:
                return column

def add_assoc(name, own, other, on_table):
    table = own.mapper.tables[-1]
    other_table = other.mapper.tables[-1]
    on_inter = table.c.id == find_fk_column(table, on_table)
    on_assoc = other_table.c.id == find_fk_column(other_table, on_table)
    def do_assoc(self):
        on_id = table.c.id==self.id
        on = on_id & on_inter & on_assoc
        return other.mapper.select(on)
    setattr(own, name, property(do_assoc))

# I use add_assoc like:
add_assoc('pages', Linklist, Page, model.linklist_page)


# The following function is what I use for amending columns (insert or update)
# * It customly binds the params in order not to exceed maximum identifier 
length
# * It prevents updating if all fetched data is equivalent to the existing data
# * It returns the id of the fetched table
def amend(table, keys, **data):
    if isinstance(keys, str):
        keys = [keys]
    params = dict((key,data[key]) for key in keys)
    clauses = [table.c[name]==sqlalchemy.bindparam(name, 
type=table.c[name].type) for name in keys]
    where = sqlalchemy.and_(*clauses)
    sql = table.select(where)
    result = sql.execute(**params).fetchone()
    if result:
        is_different = [(name,value, result[name]) for name, value in 
data.items() if value != result[name]]
        if len(is_different):
            table.update(where).execute(**data)
        return result.id
    else:
        insert_sql = table.insert()
        insert_sql.execute(**data)
        return table.engine.last_inserted_ids()[0]

# I use it like:
amend(sometable, ['foo', 'bar'], foo=1, bar='asdf', blubber=3)

Reply via email to