Hello,

I'm trying to write a custom REPLACE expression that compiles differently 
on MySQL vs sqlite, namely it would look like REPLACE INTO in mysql and 
INSERT OR REPLACE in sqlite. I implemented it like so:

class ReplaceInto(ValuesBase):
    def __init__(self, table, values=None):
        super(ReplaceInto, self).__init__(table, values, None)

@compiles(ReplaceInto)
def visit_replace_into(element, compiler, **kw):
    return 'REPLACE INTO %s(%s) VALUES (%s)' % (
        compiler.process(element.table, asfrom=True),
        ', '.join(element.parameters.keys()),
        "'" + "', '".join(element.parameters.values()) + "'"
    )

@compiles(ReplaceInto, 'sqlite')
def visit_replace_into_sqlite(element, compiler, **kw):
    return 'INSERT OR REPLACE INTO %s(%s) VALUES (%s)' % (
        compiler.process(element.table, asfrom=True),
        ', '.join(element.parameters.keys()),
        "'" + "', '".join(element.parameters.values()) + "'"
    )

But this seems brittle and prone to SQL injection attacks. I'm wondering if 
there is SQLAlchemy API I should be reusing in the 
visit_replace_into_sqlite methods to write this better?

On a separate note, the above works when you do:

r = ReplaceInto(table, {'some_colname', 'some_value'})

But does not work if I do this:

r = ReplaceInto(table).values(some_colname = 'some_value')

Because in the latter case, element.parameters would be None in 
visit_replace_into, even though I'm inheriting from ValuesBase.

Feedback is much appreciated,
Samer

-- 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to