Domanda

Vorrei utilizzare caricamento automatico di utilizzare un database existings. Io so come farlo senza sintassi dichiarativa (modello / _ init _ py.):

def init_model(engine):
    """Call me before using any of the tables or classes in the model"""
    t_events = Table('events', Base.metadata, schema='events', autoload=True, autoload_with=engine)
    orm.mapper(Event, t_events)

    Session.configure(bind=engine)  

class Event(object):
    pass

Questo funziona bene, ma vorrei usare la sintassi dichiarativa:

class Event(Base):
    __tablename__ = 'events'
    __table_args__ = {'schema': 'events', 'autoload': True}

Purtroppo, in questo modo ottengo:

sqlalchemy.exc.UnboundExecutionError: Nessun motore è legato ai metadati di questa tabella. Passare un motore per la tabella tramite autoload_with = , o associare i metadati con un motore tramite metadata.bind =

Il problema qui è che non so dove trovare il motore da (per usarlo in autoload_with) in fase di importazione del modello (è disponibile in init_model ()). Ho provato ad aggiungere

meta.Base.metadata.bind(engine)

per environment.py, ma non funziona. Chiunque ha trovato qualche soluzione elegante?

È stato utile?

Soluzione

OK, credo di aver capito. La soluzione è dichiarare gli oggetti del modello al di fuori del model/__init__.py. Ho concluso che __init__.py viene importato come il primo file durante l'importazione qualcosa da un modulo (in questo caso model) e questo causa problemi, perché gli oggetti del modello vengono dichiarati prima init_model() è chiamato.

Per evitare questo ho creato un nuovo file nel modulo model, per esempio objects.py. Ho poi dichiarato tutti i miei oggetti del modello (come Event) in questo file.

Poi, posso importare i miei modelli in questo modo:

from PRJ.model.objects import Event

Inoltre, per evitare di specificare autoload-with per ogni tabella, ho inserito questa riga alla fine del init_model():

Base.metadata.bind = engine

In questo modo posso dichiarare il mio modello di oggetti senza codice standard, in questo modo:

class Event(Base):
    __tablename__ = 'events'
    __table_args__ = {'schema': 'events', 'autoload': True}

    event_identifiers = relationship(EventIdentifier)

    def __repr__(self):
        return "<Event(%s)>" % self.id

Altri suggerimenti

Ho appena provato questo modulo ORM utilizzando.

Base = declarative_base(bind=engine)

Base.metadata.reflect(bind=engine)

Accesso tabelle manualmente o attraverso l'anello o qualsiasi altra cosa:

Base.metadata.sorted_tables

potrebbe essere utile.

Controlla la Utilizzando SQLAlchemy con piloni esercitazione su come associare i metadati al motore nella funzione init_model.

Se l'istruzione meta.Base.metadata.bind(engine) si lega con successo i metadati del modello al motore, si dovrebbe essere in grado di eseguire questa inizializzazione la propria funzione init_model. Credo che non volevi saltare vincolante i metadati in questa funzione, vero?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top