sql >> Databáze >  >> RDS >> PostgreSQL

Sqlalchemy:aktualizace sekundárního vztahu

Problém je v tom, že se chcete ujistit, že instance, které vytvoříte, jsou jedinečné. Můžeme vytvořit alternativní konstruktor, který zkontroluje mezipaměť existujících nepotvrzených instancí nebo se dotáže databáze na existující potvrzenou instanci, než vrátí novou instanci.

Zde je ukázka takové metody:

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

create_unique metoda byla inspirována příkladem z wiki SQLAlchemy . Tato verze je mnohem méně spletitá a upřednostňuje jednoduchost před flexibilitou. Použil jsem to v produkčních systémech bez problémů.

Samozřejmě existují vylepšení, která lze přidat; toto je jen jednoduchý příklad. get_unique metoda může být zděděna z UniqueMixin , které lze použít pro libovolný počet modelů. Mohlo by být implementováno flexibilnější zapamatování argumentů. To také odkládá problém více vláken vkládajících konfliktní data zmíněný Ants Aasma; zpracování, které je složitější, ale mělo by být zjevným rozšířením. Nechám to na vás.



  1. Sql Server 2008 R2 Management Studio - bez Intellisense

  2. Android Studio 3.0 canary 1 :Chyba syntaxe SQL

  3. Nelze se připojit k mysql přes servlet

  4. problém podobný mysql při částečné shodě