यह SQLALchemy रेसिपी अच्छा और सुरुचिपूर्ण काम करती है।
पहली बात यह है कि एक फ़ंक्शन को परिभाषित करने के लिए जिसे सत्र के साथ काम करने के लिए दिया जाता है, और एक शब्दकोश को सत्र () के साथ जोड़ा जाता है जो वर्तमान अद्वितीय कुंजी का ट्रैक रखता है ।
def _unique(session, cls, hashfunc, queryfunc, constructor, arg, kw):
cache = getattr(session, '_unique_cache', None)
if cache is None:
session._unique_cache = cache = {}
key = (cls, hashfunc(*arg, **kw))
if key in cache:
return cache[key]
else:
with session.no_autoflush:
q = session.query(cls)
q = queryfunc(q, *arg, **kw)
obj = q.first()
if not obj:
obj = constructor(*arg, **kw)
session.add(obj)
cache[key] = obj
return obj
इस फ़ंक्शन का उपयोग करने का एक उदाहरण एक मिश्रण में होगा:
class UniqueMixin(object):
@classmethod
def unique_hash(cls, *arg, **kw):
raise NotImplementedError()
@classmethod
def unique_filter(cls, query, *arg, **kw):
raise NotImplementedError()
@classmethod
def as_unique(cls, session, *arg, **kw):
return _unique(
session,
cls,
cls.unique_hash,
cls.unique_filter,
cls,
arg, kw
)
और अंत में अद्वितीय get_or_create मॉडल बनाना:
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
engine = create_engine('sqlite://', echo=True)
Session = sessionmaker(bind=engine)
class Widget(UniqueMixin, Base):
__tablename__ = 'widget'
id = Column(Integer, primary_key=True)
name = Column(String, unique=True, nullable=False)
@classmethod
def unique_hash(cls, name):
return name
@classmethod
def unique_filter(cls, query, name):
return query.filter(Widget.name == name)
Base.metadata.create_all(engine)
session = Session()
w1, w2, w3 = Widget.as_unique(session, name='w1'), \
Widget.as_unique(session, name='w2'), \
Widget.as_unique(session, name='w3')
w1b = Widget.as_unique(session, name='w1')
assert w1 is w1b
assert w2 is not w3
assert w2 is not w1
session.commit()
नुस्खा विचार में गहराई से जाता है और विभिन्न दृष्टिकोण प्रदान करता है, लेकिन मैंने इसे बड़ी सफलता के साथ उपयोग किया है।
session.merge
: stackoverflow.com/questions/12297156/…