Search code examples
pythonormpeewee

Unique together constraint using peewee


Is it way to apply unique by two columns constraint to model using peewee. There are raw way (using SQL()) but I'm finding another.

Updated:

I'm using postgres so I tried to do like @booshong says below then in raw SQL I gave the following (for simplicity transaction related BEGIN and COMMIT omitted and output was intended):

CREATE TABLE IF NOT EXISTS "foo" (
    "id" SERIAL NOT NULL PRIMARY KEY,
    "field_1" VARCHAR(255) NOT NULL,
    "field_2" VARCHAR(255) NOT NULL);

CREATE UNIQUE INDEX IF NOT EXISTS "foo_field_1_field_2" 
    ON "foo" ("field_1", "field_2");

CREATE TABLE IF NOT EXISTS "foo2" (
    "id" SERIAL NOT NULL PRIMARY KEY,
    "field_1" VARCHAR(255) NOT NULL,
    "field_2" VARCHAR(255) NOT NULL, 
    UNIQUE (field_1, field_2));

And as we can see it's different things as I say earlier.


Solution

  • 
    class Foo(BaseModel):
        field_1 = CharField()
        field_2 = CharField()
    
        class Meta:
            indexes = (
                (('field_1', 'field_2'), True),
            )
    
    
    class Foo2(BaseModel):
        field_1 = CharField()
        field_2 = CharField()
    
        class Meta:
            constraints = [SQL('UNIQUE (field_1, field_2)')]
    
    
    Foo.create_table()
    Foo2.create_table()
    
    
    -- MySQL v8
    
    show create table foo;
    >> CREATE TABLE `foo` (
      `id` int NOT NULL AUTO_INCREMENT,
      `field_1` varchar(255) NOT NULL,
      `field_2` varchar(255) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `foo_field_1_field_2` (`field_1`,`field_2`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
    
    
    show create table foo2;
    >> CREATE TABLE `foo2` (
      `id` int NOT NULL AUTO_INCREMENT,
      `field_1` varchar(255) NOT NULL,
      `field_2` varchar(255) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `field_1` (`field_1`,`field_2`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
    

    The two tables are equivalent.