Pg8000アダプターを使用してデータベースに接続し、SQLAlchemy 1.1.5を使用してPostgresqlデータベースにタイプuuidの主キーIDを設定します。 SQLAlchemyのドキュメントにある Backend-agnostic GUID TypeRecipe を使用しました。
データベースに挿入したいとき、次のエラーが出ます
File ".../guid.py", line ???, in process_result_value
return uuid.UUID(value)
File "/usr/lib/python2.7/uuid.py", line 131, in __init__
hex = hex.replace('urn:', '').replace('uuid:', '')
AttributeError: 'UUID' object has no attribute 'replace'
私のモデルはこのように見えます
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from guid import GUID
import uuid
base = declarative_base()
class Item(base):
__tablename__ = 'item'
id = Column(GUID(), default=uuid.uuid4, nullable=False, unique=True, primary_key=True)
name = Column(String)
description = Column(String)
def __repr__(self):
return "<Item(name='%s', description='%s')>" % (self.name, self.description)
私のリソースまたはコントローラーはこのように見えます
data = req.params
item = Item(name=data['name'], description=data['description'])
self.session.add(item)
self.session.commit()
_pg8000
_ PostgreSQLデータベースアダプターはuuid.UUID()
オブジェクトを返します(それらの タイプマッピングのドキュメントを参照 を参照)。SQLAlchemyはそれを TypeDecorator.process_result_value()
に渡しましたメソッド 。
ドキュメントで与えられた実装はstringを予期していましたが、これは失敗しました:
_>>> import uuid
>>> value = uuid.uuid4()
>>> uuid.UUID(value)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python2.7/uuid.py", line 133, in __init__
hex = hex.replace('urn:', '').replace('uuid:', '')
AttributeError: 'UUID' object has no attribute 'replace'
_
簡単な回避策は、とにかく値を文字列にすることです:
_def process_result_value(self, value, dialect):
if value is None:
return value
else:
return uuid.UUID(str(value))
_
または、最初にタイプをテストできます。
_def process_result_value(self, value, dialect):
if value is None:
return value
else:
if not isinstance(value, uuid.UUID):
value = uuid.UUID(value)
return value
_
ドキュメントでこれを修正するために pull request#4 を送信しました(マージされたため)。
これはそれを修正するはずです:
_id = Column(GUID(as_uuid=True), ...)
_
from https://bitbucket.org/zzzeek/sqlalchemy/issues/3323/in-099-uuid-columns-are-broken-with :
「
UUID()
オブジェクトを渡す場合は、_as_uuid
_フラグをTrueに設定する必要があります。」
システム全体でUUIDを使用する場合、これはかなりイライラすることがあります。特定の条件下では、UUIDが文字列として送られるか、未加工のUUIDとして送られるかを制御することが難しい場合があります。これを回避するには、このような解決策が機能する場合があります。ドキュメントの例を添付して、他のすべてがまだ正しいことを確認します。
# TODO: Set this up such that the normal uuid interface is available as a pass through
import uuid
class UUID(uuid.UUID):
def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None,
int=None, version=None):
if hex and (issubclass(type(hex), uuid.UUID) or isinstance(hex, uuid.UUID)):
hex = str(hex)
super(UUID, self).__init__(hex=hex, bytes=bytes, bytes_le=bytes_le, fields=fields, int=int, version=version)
print(UUID(uuid4())) # Now this works!
print(UUID('{12345678-1234-5678-1234-567812345678}'))
print(UUID('12345678123456781234567812345678'))
print(UUID('urn:uuid:12345678-1234-5678-1234-567812345678'))
print(UUID(bytes=b'\x12\x34\x56\x78' * 4)) # Python 3 requires this to be prefixed with b''. Docs appear to be mainly for Python 2
print(UUID(bytes_le=b'\x78\x56\x34\x12\x34\x12\x78\x56' +
b'\x12\x34\x56\x78\x12\x34\x56\x78'))
print(UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678)))
print(UUID(int=0x12345678123456781234567812345678))
これは独自の裁量で使用してください。これは単なる例です。