94056


# やりたいこと

標題通り、あるテーブルのカラムの値を特定の文字列だけ許可するようにsqlalchemyで記述するにはどのようにすれば良いでしょうか？  
insert/updateされたときに、文字列に合致しない場合にはエラーとして処理して、受け付けないようにしたいです。

# 環境

Python 3.9  
Windows10

[code]

    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy import Column, String
    from sqlalchemy.dialects.mysql import INTEGER
    
    # このリストの値に制限したい
    mode_type_list = [
        'DEFAULT',
        'RIGHT',
        'LEFT',
        'CENTER'
    ]
    
    
    Base = declarative_base()
    RDB_PATH = 'sqlite:///db.sqlite3'
    ECHO_LOG = True
    
    engine = create_engine(
        RDB_PATH, echo=ECHO_LOG
    )
    
    class Test(Base):
        __tablename__ = 'test_tbl'
        key = Column(
            'pkey',
            INTEGER(unsigned=True),
            primary_key=True,
            autoincrement=True,
        )
        key = Column('mode_type', String(256))
    
        def __init__(self,mode_type:str):
            self.mode_type = mode_type
    
    Session = sessionmaker(bind=engine)
    session = Session()
    
    Base.metadata.create_all(engine)
    
    param = Test(mode_type='DEFAULT')
    session.add(param)
    
    session.commit()
    
    
    
[/code]


CC BY-SA 4.0
2023-03-01T08:41:58.870
94049
2023-03-03T07:33:47.657
32891
question
python sqlalchemy
sqlalchemyを用いて、カラムの値を文字列リスト内の文字列に制限する方法


enum使うとよいかも

定義部分で Pythonの `enum` と sqlalchemyの `Enum` を指定し, `enum.Enum` でクラスを作成  
(必要であれば, `value` を文字列で指定も可能 … 詳しくは [enum ---
列挙型のサポート](https://docs.python.org/ja/3/library/enum.html))

[code]

    import enum
    
    from sqlalchemy import Table, Column, Integer, String, Enum   # ⇐ Enum を追加
    
    # このリストの値に制限したい
    mode_type_list = [
        'DEFAULT',
        'RIGHT',
        'LEFT',
        'CENTER'
    ]
    ModeType = enum.Enum('ModeType', mode_type_list)
    
[/code]

`ModeType` の要素(？) の確認

[code]

    In [3]: [e for e in ModeType]
    Out[3]:
    [<ModeType.DEFAULT: 1>,
     <ModeType.RIGHT: 2>,
     <ModeType.LEFT: 3>,
     <ModeType.CENTER: 4>]
    
[/code]

カラム指定とデータ追加の部分

`ModeType`を文字列で指定するなら `ModeType['DEFAULT']` で可能  
`ModeType.DEFAULT == ModeType['DEFAULT']` で同じものを指します

[code]

    class Test(Base):
    
        # カラム指定
        mode_type = Column('mode_type', Enum(ModeType))
    
    with Session() as session, session.begin():
        param = Test(mode_type=ModeType.DEFAULT)   # 文字列でなら ModeType['DEFAULT']
        session.add(param)
    
[/code]

* * *

#### (追記)実行結果など

実行すると, ログに以下の内容が出るはずで `VARCHAR(7)`として扱われる模様

[code]

    CREATE TABLE test_tbl (
        pkey INTEGER NOT NULL, 
        mode_type VARCHAR(7), 
        PRIMARY KEY (pkey)
    )
    
[/code]

内容の確認

[code]

    from sqlalchemy import text
    with Session() as session:
        result = session.execute(text('SELECT * FROM test_tbl'))
        for row in result:
            print(row)
    # (1, 'DEFAULT')
    
[/code]


CC BY-SA 4.0
2023-03-02T10:24:39.387
94056
2023-03-03T07:33:47.657
2023-03-03T07:33:47.657
43025
43025
94049
answer