我想使用sqlalchemy 1.1.5在PostgreSQL数据库中使用一个主密钥ID,并使用PG8000适配器连接到数据库。我使用了SQLalchemy文档中的 Backend-Agnostic Guid Type 食谱。
当我想插入数据库时,我会收到以下错误
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()
这应该修复:
id = Column(GUID(as_uuid=True), ...)
来自https://bitbucket.org/zzzeek/sqlalchemy/issues/3323/in-099-uuid-columns-columns-are-broken-with:
"如果要通过
UUID()
对象,则必须将as_uuid
标志设置为true。"
pg8000
PostgreSQL数据库适配器正在返回uuid.UUID()
对象(请参阅其类型映射文档,而SQLalchemy已将其传递给TypeDecorator.process_result_value()
方法。
文档中给出的实现预期A 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
我已经提交了拉动请求#403以在文档中进行修复(自合并)。
这里的实际问题是您有default=uuid.uuid4
,Postgres期望以UUID格式使用字符串。您需要default=lambda: str(uuid.uuid4())
这在系统上使用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'x12x34x56x78' * 4)) # Python 3 requires this to be prefixed with b''. Docs appear to be mainly for Python 2
print(UUID(bytes_le=b'x78x56x34x12x34x12x78x56' +
b'x12x34x56x78x12x34x56x78'))
print(UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678)))
print(UUID(int=0x12345678123456781234567812345678))
请使用自己的酌处权,这只是一个例子。
i遇到相同的问题,并搜索了两天,然后才发现该错误之前的代码包含错误:
它遇到以下错误,指python和sqlalchemy中的错误
offertemodule_1 | File "/opt/packages/database/models.py", line 79, in process_bind_param
offertemodule_1 | return "%.32x" % uuid.UUID(value).int
offertemodule_1 | File "/usr/local/lib/python3.7/uuid.py", line 157, in __init__
offertemodule_1 | hex = hex.replace('urn:', '').replace('uuid:', '')
offertemodule_1 | sqlalchemy.exc.StatementError: (builtins.AttributeError) 'builtin_function_or_method' object has no attribute 'replace'
offertemodule_1 | [SQL: SELECT product.id AS product_id, product.supplier_id AS product_supplier_id, product.supplier_product_url AS product_supplier_product_url, product.supplier_product_id AS product_supplier_product_id, product.title AS product_title, product.description AS product_description, product.brand AS product_brand, product.product_line AS product_product_line, product.buying_price_ex_vat AS product_buying_price_ex_vat, product.buying_vat AS product_buying_vat, product.vat_pct AS product_vat_pct, product.advise_price AS product_advise_price, product.estimated_days_leadtime AS product_estimated_days_leadtime, product.product_category AS product_product_category, product.nestedproducts AS product_nestedproducts, product.atttibutes_meta AS product_atttibutes_meta, product.statistics_meta AS product_statistics_meta, product.active AS product_active, product.created AS product_created, product.created_by AS product_created_by, product.modified AS product_modified, product.modified_by AS product_modified_by
offertemodule_1 | FROM product
offertemodule_1 | WHERE product.id = %(id_1)s]
offertemodule_1 | [parameters: [immutabledict({})]]
,但事实证明,在此之前,一个过程将错误的对象发送到我的数据库函数
@ns_products.route('/<string:product_id>')
@api.response(404, 'product not found.')
class Details(Resource):
@api.marshal_with(product)
@api.doc(security='jwt')
@jwt_required
def get(self, product_id):
'''Returns a single product instance'''
return Product.get(id)`
应该是(注意'product_id')
@ns_products.route('/<string:product_id>')
@api.response(404, 'product not found.')
class Details(Resource):
@api.marshal_with(product)
@api.doc(security='jwt')
@jwt_required
def get(self, product_id):
'''Returns a single product instance'''
return Product.get(product_id)
因此,存储在product_id中的UUID弦实际上是本机Python对象" ID"。因此,它试图将字符串处理为UUID并失败。
如果您使用models.py,则解决方案非常容易。
从partner_trx_id = models.UUIDField(null=True, db_column="partner_trx_id")
到partner_trx_id = models.CharField(max_length=35,null=True, db_column="partner_trx_id")
django查询无法读取uuidfield,所以我们更改为charfield。
如果您想了解更多信息,请访问https://code.djangoproject.com/ticket/30526。
我在不使用表单的情况下遇到了这个问题,影响了我的ORM。我正在运行psycopg2。对我的修复是:
sudo pip install psycopg2-binary
重新启动Apache后,我看不到Psycopg2-Binary版本2.7.5
attributeError:'uuid'对象没有属性'get_hex'
解决方案在python2中使用-UUID.UUID4()。get_hex()以上在Python3中效果不佳。必须使用-UUID.UUID4()。hex remove get_hex()。它的效果很好。