2017-11-09 3 views
0

Hier ist mein Beitrag Modell:Wie Verwenden von Enum mit SQLAlchemy und Alembic?

class Post(Base): 
    __tablename__ = 'posts' 

    title = db.Column(db.String(120), nullable=False) 
    description = db.Column(db.String(2048), nullable=False) 

Ich mag würde Enum hinzufügen status zu. Also, ich habe ein neues Enum erstellt:

import enum 

class PostStatus(enum.Enum): 
    DRAFT='draft' 
    APPROVE='approve' 
    PUBLISHED='published' 

Und hat ein neues Feld zu modellieren:

class Post(Base): 
    ... 
    status = db.Column(db.Enum(PostStatus), nullable=False, default=PostStatus.DRAFT.value, server_default=PostStatus.DRAFT.value) 

Nach FLASK_APP=server.py flask db migrate tun, eine solche Migration generiert wurde:

def upgrade(): 
    op.add_column('posts', sa.Column('status', sa.Enum('DRAFT', 'APPROVE', 'PUBLISHED', name='poststatus'), server_default='draft', nullable=False)) 

Nach versuchen, DB zu aktualisieren, bekomme ich:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) type "poststatus" does not exist 
LINE 1: ALTER TABLE posts ADD COLUMN status poststatus DEFAULT 'draf... 
              ^
[SQL: "ALTER TABLE posts ADD COLUMN status poststatus DEFAULT 'draft' NOT NULL"] 
  1. Warum wurde der Typ poststatus nicht automatisch auf DB-Ebene erstellt? In der ähnlichen Migration war es.
  2. Wie spezifiziert man server_default Option richtig? Ich benötige sowohl ORM-Level-Standardwerte als auch DB-Level-Standards, da ich vorhandene Zeilen ändere, sodass ORM-Standardwerte nicht angewendet werden.
  3. Warum reale Werte in der DB sind "ENTWURF", "APPROVE", "VERÖFFENTLICHT", aber nicht draft, etc? Ich vermutete, dass es ENUM-Werte geben sollte, keine Namen.

Vielen Dank im Voraus.

Antwort

-1

Von offizieller Dokumentation: https://docs.python.org/3/library/enum.html#creating-an-enum

import enum 

class PostStatus(enum.Enum): 
    DRAFT = 0 
    APPROVE = 1 
    PUBLISHED = 2 

Nach diesem:

class Post(Base): 
    ... 
    status = db.Column(db.Integer(), nullable=False, default=PostStatus.DRAFT.value, server_default=PostStatus.DRAFT.value) 

1) PostStatus ist kein DB-Modell, es ist nur eine Klasse, die Status-IDs enthält;

2) es ist OK

3) Sie müssen Status Strings in DB nicht speichern, sollten Sie besser ids verwenden stattdessen

+0

Ich sehe nicht, wie Sie Ihren Beitrag die Frage beantwortet; 1) für ENUMs in Postgres muss ein neuer Postgres-Enum-Typ erstellt werden (und der Autor verwendet Postgres) 3) Ich denke nicht, dass das in irgendeiner Weise hilft, wenn Sie Postgres verwenden, da Postgres nicht speichern wird diese als Zeichenketten, nur Verweis auf die jeweiligen Enum-Typ-Werte; Es wird auch viel einfacher zu verstehen, was die Werte sind, wenn sie Zeichenfolgen sind, wenn Sie die Rohwerte zu jeder Zeit betrachten müssen Siehe https://Stackoverflow.com/a/37860817/294579 für eine funktionierende Lösung zu dieses Problem. –

+0

Woher wissen Sie, welche Version der Autor verwendet? Gibt es irgendetwas in der Post, das ich vermisst habe? –

Verwandte Themen