এই 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/…