我有一个现有的数据库架构,它使用整数作为主键,并且需要向每个表添加第二个 UUID 列。这个 UUID 是服务的消费者在引用记录时将使用的,现有的整数 ID 将保持私有并且仅在内部使用。下面是一个简化的例子。事务表具有 TransactionID 和 TransactionUUID 列,并且还具有指向 Category 表的外键 CategoryID。同样,Category 表具有 CategoryID 和 CategoryUUID 列。
+------------+--------------------------------------+------+
| CategoryID | CategoryUUID | Name |
+------------+--------------------------------------+------+
| 1 | f9aafcf6-8cc7-4f1e-a847-bfbb0297bc5f | Foo |
| 2 | 1cf892e3-c100-4542-bfd1-131ba8a18c17 | Bar |
+------------+--------------------------------------+------+
+---------------+--------------------------------------+---------+---------------------+------------+
| TransactionID | TransactionUUID | Amount | Time | CategoryID |
+---------------+--------------------------------------+---------+---------------------+------------+
| 1 | 48182040-beb5-4df8-98fe-c3f6f5557cc0 | 55.0000 | 2021-07-15 09:56:11 | 2 |
+---------------+--------------------------------------+---------+---------------------+------------+
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from marshmallow import fields, post_load
db = SQLAlchemy()
ma = Marshmallow()
class Category(db.Model):
__tablename__ = 'Category'
id = db.Column('CategoryID', db.Integer, primary_key=True)
uuid = db.Column('CategoryUUID', db.CHAR(36), unique=True, nullable=False)
name = db.Column('Name', db.String(64), nullable=False)
transactions = db.relationship('Transaction', back_populates='category')
class CategorySchema(ma.Schema):
uuid = fields.UUID()
name = fields.Str()
@post_load
def make_category(self, data, **kwargs):
return Category(**data)
class Transaction(db.Model):
__tablename__ = 'Transaction'
id = db.Column('TransactionID', db.Integer, primary_key=True)
uuid = db.Column('TransactionUUID', db.CHAR(36), unique=True, nullable=False)
amount = db.Column('Amount', db.DECIMAL, nullable=False)
time = db.Column('Time', db.DateTime, nullable=False)
category_id = db.Column('CategoryID', db.Integer, db.ForeignKey('Category.CategoryID'), nullable=False)
category = db.relationship('Category', back_populates='transactions')
class TransactionSchema(ma.Schema):
uuid = fields.UUID()
amount = fields.Decimal()
time = fields.DateTime()
category_uuid = fields.UUID()
@post_load
def make_transaction(self, data, **kwargs):
return Transaction(**data)
我想要实现的是允许对事务资源的发布请求以允许创建新事务,并以某种方式将 TransactionSchema 类中的 category_uuid 字段链接到相应的 category_id。我面临的挑战是在序列化和反序列化对象时如何将 UUID 与其对应的整数 ID 相关联。例如,当一个新事务被创建并且消费者通过这样的有效负载发布时:
{
"uuid": "7f68e33f-c5d2-41c8-9826-5df904722a1a",
"amount": 10.00,
"time": "2021-07-17T04:50:25+00:00",
"category_uuid": "f9aafcf6-8cc7-4f1e-a847-bfbb0297bc5f"
}
JSON 对象反序列化如下:
transaction = TransactionSchema().load({...})
Transaction 类没有 category_uuid 属性,需要以某种方式将此值转换为相应的整数 ID。同样,当像这样序列化事务时:
json = TransactionSchema().dump(transaction)
category_id 属性需要翻译成对应的 category_uuid 值。
sqlalchemy 中是否有一种优雅的方式来实现这种 ID 映射?