2013-03-27 8 views
8

マイUserモデルはsqlalchemy docsで説明したようにGUIDは、カスタム型であるAlembic:モデルでカスタムタイプを移行する方法は?私は</p> <pre><code>alembic revision --autogenerate -m "Added initial table" </code></pre> <p>を実行したときに

class User(UserMixin, db.Model): 
    __tablename__ = 'users' 
    # noinspection PyShadowingBuiltins 
    uuid = Column('uuid', GUID(), default=uuid.uuid4, primary_key=True, 
        unique=True) 
    email = Column('email', String, nullable=False, unique=True) 
    _password = Column('password', String, nullable=False) 
    created_on = Column('created_on', sa.types.DateTime(timezone=True), 
         default=datetime.utcnow()) 
    last_login = Column('last_login', sa.types.DateTime(timezone=True), 
         onupdate=datetime.utcnow()) 

(全く同じ)である

は今、私は私のupgrade()

としての取得します
def upgrade(): 
    ### commands auto generated by Alembic - please adjust! ### 
    op.create_table('users', 
    sa.Column('uuid', sa.GUID(), nullable=False), 
    sa.Column('email', sa.String(), nullable=False), 
    sa.Column('password', sa.String(), nullable=False), 
    sa.Column('created_on', sa.DateTime(timezone=True), nullable=True), 
    sa.Column('last_login', sa.DateTime(timezone=True), nullable=True), 
    sa.PrimaryKeyConstraint('uuid'), 
    sa.UniqueConstraint('email'), 
    sa.UniqueConstraint('uuid') 
    ) 
    ### end Alembic commands ### 

しかし、適用、アップグレード中 - >alembic upgrade head、私が見

File "alembic/versions/49cc74d0da9d_added_initial_table.py", line 20, in upgrade 
    sa.Column('uuid', sa.GUID(), nullable=False), 
AttributeError: 'module' object has no attribute 'GUID' 

どのように私はそれがGUID /カスタムここに入力して動作させることができますか?

答えて

7

sa.GUID()は、方言に応じてsa.CHAR(32)またはUUID()(インポートラインの追加後はfrom sqlalchemy.dialects.postgresql import UUID)のいずれかに置き換えることができます。

GUID()(インポートラインを追加した後に)from your.models.custom_types import GUIDを置き換えることもできますが、アップグレードスクリプトはモデルコードに関連付けられていますが、これはうまくいかない場合があります。

+0

しかし、もし私が 'sqlite'を使っていればテストで壊れてしまいますが、それは一貫していませんよね? – daydreamer

+1

私は実際には、テスト環境が生産に密接に従う必要があるので、テストで 'sqlite'を使うのはあまり気にしません。それ以外に、複数の方言に対して同じコードをデプロイしていますか? – sayap

+0

とにかく、移行スクリプトは現時点では実際のスキーマと一貫していて、コードとの一貫性はコードが永遠に変化しているので駄目です。 – sayap

3

私は同様の問題を持っていたようにそれを解決するには、次のとおりです。

のは、あなたが(マイナー命名変更ですでに引用ページから)を含む、以下のモジュールmy_guidを持っていると仮定しましょう:

import uuid as uuid_package 
from sqlalchemy.dialects.postgresql import UUID as PG_UUID 
from sqlalchemy import TypeDecorator, CHAR 

class GUID(TypeDecorator): 
    impl = CHAR 

    def load_dialect_impl(self, dialect): 
     if dialect.name == 'postgresql': 
      return dialect.type_descriptor(PG_UUID()) 
     else: 
      return dialect.type_descriptor(CHAR(32)) 

    def process_bind_param(self, value, dialect): 
     if value is None: 
      return value 
     elif dialect.name == 'postgresql': 
      return str(value) 
     else: 
      if not isinstance(value, uuid_package.UUID): 
       return "%.32x" % uuid_package.UUID(value) 
      else: 
       # hexstring 
       return "%.32x" % value 

    def process_result_value(self, value, dialect): 
     if value is None: 
      return value 
     else: 
      return uuid_package.UUID(value) 

私のために働いた
from my_guid import GUID 
import sqlalchemy as sa 
sa.GUID = GUID 

:あなたのモデルでこのGUIDを使用する場合は、あなただけのalembic/env.pyの3行を追加する必要があります。希望が助けてくれる!

+1

私のために働きました。ありがとう。 – Soferio

+0

Second - これは私のために働きましたが、この質問や他の質問に関する多くの答えはそうではありませんでした。ありがとう! –

1

implアトリビュートクラスの__repr__機能を使用すると、ほとんどのカスタムタイプでうまくいきました。マイグレーション定義をクラスの中に入れておき、代わりにenv.pyまたはscripts.py.makoにインポートを入れることを心配しています。さらに、モジュール間でコードを簡単に移動できます。

Class GUID(types.TypeDecorator) 
    impl = CHAR 

    def __repr__(self): 
     return self.impl.__repr__() 

    # You type logic here. 

自動移行でCHAR(length=XXX)が生成されます。

関連する問題

 関連する問題