sql >> Database >  >> RDS >> PostgreSQL

Sqlalchemy:secundaire relatie-update

Het probleem is dat u zeker wilt weten dat de instances die u maakt uniek zijn. We kunnen een alternatieve constructor maken die een cache van bestaande niet-gecommitteerde instanties controleert of de database doorzoekt naar een bestaande vastgelegde instantie voordat een nieuwe instantie wordt geretourneerd.

Hier is een demonstratie van een dergelijke methode:

from sqlalchemy import Column, Integer, String, ForeignKey, Table
from sqlalchemy.engine import create_engine
from sqlalchemy.ext.declarative.api import declarative_base
from sqlalchemy.orm import sessionmaker, relationship

engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(engine)
Base = declarative_base(engine)

session = Session()


class Role(Base):
    __tablename__ = 'role'

    id = Column(Integer, primary_key=True)
    name = Column(String, nullable=False, unique=True)

    @classmethod
    def get_unique(cls, name):
        # get the session cache, creating it if necessary
        cache = session._unique_cache = getattr(session, '_unique_cache', {})
        # create a key for memoizing
        key = (cls, name)
        # check the cache first
        o = cache.get(key)
        if o is None:
            # check the database if it's not in the cache
            o = session.query(cls).filter_by(name=name).first()
            if o is None:
                # create a new one if it's not in the database
                o = cls(name=name)
                session.add(o)
            # update the cache
            cache[key] = o
        return o


Base.metadata.create_all()

# demonstrate cache check
r1 = Role.get_unique('admin')  # this is new
r2 = Role.get_unique('admin')  # from cache
session.commit()  # doesn't fail

# demonstrate database check
r1 = Role.get_unique('mod')  # this is new
session.commit()
session._unique_cache.clear()  # empty cache
r2 = Role.get_unique('mod')  # from database
session.commit()  # nop

# show final state
print session.query(Role).all()  # two unique instances from four create calls

De create_unique methode is geïnspireerd op het voorbeeld uit de SQLAlchemy wiki . Deze versie is veel minder ingewikkeld en verkiest eenvoud boven flexibiliteit. Ik heb het zonder problemen in productiesystemen gebruikt.

Er zijn uiteraard verbeteringen die kunnen worden toegevoegd; dit is slechts een eenvoudig voorbeeld. De get_unique methode kan worden overgenomen van een UniqueMixin , te gebruiken voor een willekeurig aantal modellen. Het flexibeler onthouden van argumenten zou kunnen worden geïmplementeerd. Dit zet ook het probleem van meerdere threads die conflicterende gegevens invoegen, genoemd door Ants Aasma, opzij; behandeling die ingewikkelder is, maar een voor de hand liggende uitbreiding zou moeten zijn. Dat laat ik aan jou over.



  1. Shuffle een tabel in MySQL met een opgeslagen procedure

  2. Gratis webhosting met PHP-ondersteuning

  3. gebruik array/variabele in sql-query

  4. php + vul het vervolgkeuzemenu in bij de selectie van een ander