Pass non dialect keywords into custom compile.

Issue #3983 resolved
Михаил Доронин
created an issue

I want to create a merge statement that would work both in mysql and sqlite. For that I need to be able pass keys for on duplicate key, but it seems that you've forbidden to pass any non dialect keywords to statements.

To be able to use sqlite in tests and mysql in production is the goal here, so polluting the code with conditionals to check what db I'm using and passing mysql_keys isn't acceptable.

Comments (5)

  1. Michael Bayer repo owner

    hi there -

    I'm not sure what "create a merge statement" means. If you are making your own class that subclasses Insert or something like that, you can pass whatever keywords you'd like to it.

    Can you please provide specifics?

  2. Михаил Доронин reporter

    I'm talking about sql Merge statement (added in sql 2003 standard) and it's analogous (insert on duplicate key update, insert or replace, insert on conflict etc)

    I want to create a cross-platform Merge.

    initally I've done this

    class Merge(Insert):

    and a custom @compiles(Merge, 'mysql') and @compiles(Mege, 'sqlite'), but that doesn't give an ability to specify what keys to use to find conflict.

    As you suggested I've done this

    class Merge(Insert):
        def __init__(self, *args, keys=(), **kwargs):
            Insert.__init__(*args, **kwargs)
            self.keys = keys

    But this gives me

    E sqlalchemy.exc.ArgumentError: FROM expression expected

    I'm testing this like that session.execute(Merge(Foo, tuple(items.values(), keys=('id',))))

  3. Михаил Доронин reporter

    @Michael Bayer

    I see you have added on conflict to postgresql dialect. Maybe I should add similar constructs to dialects that I'm interested? Seems like there is none for mysql and sqlite. And then somehow create a new Merge statement that would first compile into dialect specific construct and only then into actual SQL? Can you provide guidance on that?

  4. Log in to comment