2013-03-31 14 views
5

Moja tabela jestsqlalchemy.exc.ProgrammingError: (ProgrammingError) nie może dostosować typ 'UUID'

categories = table('categories', 
         Column('uuid', UUID(), default=uuid.uuid4, 
           primary_key=True, 
           unique=True, autoincrement=False), 
         Column('name', String), 
         Column('parent', String), 
         Column('created_on', sa.types.DateTime(timezone=True), 
           default=datetime.utcnow()) 
    ) 

gdy próbuję wstawić dane, widzę

sqlalchemy.exc.ProgrammingError: (ProgrammingError) can't adapt type 'UUID' 'INSERT INTO categories (uuid, name, parent, created_on) VALUES (%(uuid)s, %(name)s, %(parent)s, %(created_on)s)' ({'created_on': datetime.datetime(2013, 3, 31, 4, 12, 26, 801940), 'name': 'Alcohol & Bars', 'parent': 'Food & Drink', 'uuid': UUID('860e5bae-b770-425f-8672-c15c49508a1f')}, {'created_on': datetime.datetime(2013, 3, 31, 4, 12, 26, 801940), 'name': 'Coffee & Tea', 'parent': 'Food & Drink', 'uuid': UUID('de6ad60e-a076-483d-90e9-93916c537583')}, 

następnie zmienić mój stół do

categories = table('categories', 
        Column('uuid', UUID(), default=str(uuid.uuid4()), 
          primary_key=True, 
          unique=True, autoincrement=False), 
        Column('name', String), 
        Column('parent', String), 
        Column('created_on', sa.types.DateTime(timezone=True), 
          default=datetime.utcnow()) 
) 

potem zaczynam widzieć błąd jak

sqlalchemy.exc.IntegrityError: (IntegrityError) duplicate key value violates unique constraint "categories_pkey" 

    DETAIL: Key (uuid)=(cb80a166-adce-4a6e-9e1a-c210d9b86732) already exists. 
    'INSERT INTO categories (uuid, name, parent, created_on) VALUES (%(uuid)s, %(name)s, %(parent)s, %(created_on)s)' ({'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Alcohol & Bars', 'parent': 'Food & Drink', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}, {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Coffee & Tea', 'parent': 'Food & Drink', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}, {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Dessert', 'parent': 'Food & Drink', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}, {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Fast Food', 'parent': 'Food & Drink', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}, {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Groceries', 'parent': 'Food & Drink', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}, {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Other', 'parent': 'Food & Drink', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}, {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Restaurants', 'parent': 'Food & Drink', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}, {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Snacks', 'parent': 'Food & Drink', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'} ... displaying 10 of 43 total bound parameter sets ... {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Other', 'parent': 'Financial', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}, {'created_on': datetime.datetime(2013, 3, 31, 4, 14, 22,7), 'name': 'Tax Preparation', 'parent': 'Financial', 'uuid': 'cb80a166-adce-4a6e-9e1a-c210d9b86732'}) 

Teraz dlaczego uuid.uuid4() daje zawsze tę samą wartość? Jak mogę rozwiązać ten problem?

Dzięki

Odpowiedz

6

na pierwszy przykład kodu do pracy, trzeba ustawić UUID(as_uuid=True) (patrz docs na UUID), inaczej DBAPI adapter spodziewa się wartość ciągu.

Twój drugi przykład nie działa, ponieważ default=str(uuid.uuid4()) przechowuje wartość ciągu, który jest generowany raz, gdy obiekt tabeli jest zdefiniowany i jest używany za każdym razem (stąd wyjątek duplikatu wartości). Trzeba przekazać funkcję tutaj, więc to być oceniana za każdym razem, gdy wiersz w brzmieniu:

default=lambda: str(uuid.uuid4()) 

Te same podpórek default=datetime.utcnow(), musi być default=datetime.utcnow. Inną rzeczą jest to, że ograniczenie unique=True nie jest potrzebne dla klucza podstawowego, ponieważ ma już gwarancję unikalności.

Powiązane problemy