SQLAlchemy – Diccionario de tags

Tengo una pregunta con respecto a la SQLAlchemy. ¿Cómo puedo agregar a mi clase asignada el atributo similar al diccionario, que asigna las claves de cadena a los valores de cadena y que se almacenará en la base de datos (en la misma u otra tabla como objeto mapeado original)? Quiero que esta agregue soporte para tags arbitrarias de mis objetos.

Encontré el siguiente ejemplo en la documentación de SQLAlchemy:

from sqlalchemy.orm.collections import column_mapped_collection, attribute_mapped_collection, mapped_collection mapper(Item, items_table, properties={ # key by column 'notes': relation(Note, collection_class=column_mapped_collection(notes_table.c.keyword)), # or named attribute 'notes2': relation(Note, collection_class=attribute_mapped_collection('keyword')), # or any callable 'notes3': relation(Note, collection_class=mapped_collection(lambda entity: entity.a + entity.b)) }) item = Item() item.notes['color'] = Note('color', 'blue') 

Pero quiero el siguiente comportamiento:

 mapper(Item, items_table, properties={ # key by column 'notes': relation(...), }) item = Item() item.notes['color'] = 'blue' 

¿Es posible en SQLAlchemy?

Gracias

La respuesta simple es .

Solo usa un proxy de asociación:

 from sqlalchemy import Column, Integer, String, Table, create_engine from sqlalchemy import orm, MetaData, Column, ForeignKey from sqlalchemy.orm import relation, mapper, sessionmaker from sqlalchemy.orm.collections import column_mapped_collection from sqlalchemy.ext.associationproxy import association_proxy 

Crear un entorno de prueba:

 engine = create_engine('sqlite:///:memory:', echo=True) meta = MetaData(bind=engine) 

Definir las tablas:

 tb_items = Table('items', meta, Column('id', Integer, primary_key=True), Column('name', String(20)), Column('description', String(100)), ) tb_notes = Table('notes', meta, Column('id_item', Integer, ForeignKey('items.id'), primary_key=True), Column('name', String(20), primary_key=True), Column('value', String(100)), ) meta.create_all() 

Clases (note el association_proxy en la clase):

 class Note(object): def __init__(self, name, value): self.name = name self.value = value class Item(object): def __init__(self, name, description=''): self.name = name self.description = description notes = association_proxy('_notesdict', 'value', creator=Note) 

Cartografía:

 mapper(Note, tb_notes) mapper(Item, tb_items, properties={ '_notesdict': relation(Note, collection_class=column_mapped_collection(tb_notes.c.name)), }) 

Entonces solo pruébalo

 Session = sessionmaker(bind=engine) s = Session() i = Item('ball', 'A round full ball') i.notes['color'] = 'orange' i.notes['size'] = 'big' i.notes['data'] = 'none' s.add(i) s.commit() print i.notes 

Que imprime

 {u'color': u'orange', u'data': u'none', u'size': u'big'} 

Pero, ¿están esos en la tabla de notas?

 >>> print list(tb_notes.select().execute()) [(1, u'color', u'orange'), (1, u'data', u'none'), (1, u'size', u'big')] 

¡¡Funciona!! 🙂

La respuesta simple es no’.

SQLAlchemy es envoltorio en una base de datos SQL.

Los ejemplos de relaciones que usted cita traducen una relación entre las tablas SQL en una estructura similar a un mapa de Python para que sea un poco más sencillo hacer las sentencias SELECT de SQL y ubicar filas en otra tabla.

los

 item.notes['color'] = Note('color', 'blue') 

es esencial porque la Note es una tabla separada con dos columnas. No puedes dejar la parte de la Note fuera.

Debe definir esta otra tabla SQL y debe crear objetos que se asignen a esa tabla SQL.