2013-07-24 9 views
9

Używam Flask dla mojego serwera python wsgi i sqlalchemy dla całego dostępu do mojej bazy danych.przy użyciu kolby-sqlalchemy bez podklasy deklaratywnej bazy

myślę chciałbym używać rozszerzenia Kolba-sqlalchemy w mojej aplikacji, ale nie chcę używać deklaratywny klasę bazową (db.Model), zamiast tego chcę użyć bazę SQLAlchemy. ext.deklaratywny.

Czy to pokonuje cały cel używania rozszerzenia?


Mój przypadek użycia:

Chciałbym rozszerzenie mi pomóc zarządzania sesjami/silników trochę lepiej, ale chciałbym, aby obsłużyć wszystkie modele oddzielnie.

Właściwie nie miałbym nic przeciwko używaniu rozszerzenia, ale chcę napisać modele strict. Przesyłam kod z aplikacji, która nie jest zbiorem kolb, a ja będę przesuwał zmiany do tego projektu. Jeśli na przykład kolba-sqlalchemy pozwala mi oszukiwać na przykład na tablecie metadanych, spowoduje to problemy, gdy kod zostanie wypchnięty. Istnieją również części mojego kodu, które wykonują wiele sprawdzeń typów (tożsamości polimorficzne), a także pamiętam, że sprawdzanie typów w Tabeli nie jest zalecane przy korzystaniu z rozszerzenia.

Odpowiedz

1

SQLAlchemy sami zaleca się używać opakowania Flask (db.Model) do projektów Flask. Mówiąc to, użyłem modelu declarative_base w kilku moich projektach Flask, gdzie było to bardziej sensowne.

To pokonuje cały cel klasy SQLAlchemy z kolby-sqlalchemy.

Oto niektóre przykładowy kod:

from sqlalchemy import * 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import relationship, sessionmaker 
import datetime 

#set up sqlalchemy 
engine = create_engine('postgresql://<username>:<password>@localhost/flask_database') 
Base = declarative_base() 
metadata = Base.metadata 
metadata.bind = engine 
Session = sessionmaker(bind=engine, autoflush=True) 
session = Session() 


class User(Base): 
    __tablename__ = 'user' 
    id = Column(Integer, primary_key=True) 
    api_owner_id = Column(Integer, ForeignKey('api.id')) 
    email = Column(String(120), unique=True) 
    username = Column(String(120), unique=True) 
    first_name = Column(String(120)) 
    last_name = Column(String(120)) 
    business_name = Column(String(120)) 
    account_type = Column(String(60)) 
    mobile_phone = Column(String(120)) 
    street = Column(String(120)) 
    street2 = Column(String(120)) 
    city = Column(String(120)) 
    state = Column(String(120)) 
    zip_code = Column(String(120)) 
    country = Column(String(120)) 
    creation_date = Column(DateTime, default=datetime.datetime.now()) 
    password = Column(String(120)) 
    #github stuffs 
    github_link = Column(Boolean, default=False) 
    github_usn = Column(String(120)) 
    github_oauth_token = Column(String(160)) 
    #balanced stuffs 
    balanced_account_uri = Column(String(120)) 
    ach_verified = Column(Boolean, default=False) 
    active = Column(Boolean, default=True) 
    profile_updated = Column(Boolean, default=False) 
    account_balance = Column(Numeric(precision=10, scale=2), default=0.00) 
    admin = Column(Boolean, default=False) 
    devapp = relationship('DevApp', backref="user", lazy="dynamic") 
    projects = relationship('Project', backref="user", lazy="dynamic") 
    proposals = relationship('Proposal', backref="user", lazy="dynamic") 
    transactions = relationship('Monies', backref="user", lazy="dynamic") 

    def __repr__(self): 
     return self.email 
+0

Sesja/bit silnika pomógł zilustrować odpowiedź. Tak więc, w mojej aplikacji do kolb, muszę przekazać sesję do użycia. Czy po każdym użyciu muszę oczyścić sesję w jakikolwiek sposób? (Może przy użyciu ** app.do_teardown_xxx **?) – user2097818

+0

Z parametrem autoflush = True w narzędziu sessionmaker nie jest konieczne czyszczenie. użytkownik = użytkownik (email = "[email protected]") session.add (użytkownik) session.commit() –

+0

Nie planuję uruchamiać tego w wielu wątkach, ale będę miał oddzielne moduły każdy przy użyciu własnej nowej sesji. Planuję przekazać Sesserowi. Moduły te będą stopniowo aktualizować. Czy po wystąpieniu każdej instancji sesji powinien istnieć jakiś powód do niepokoju o integralność danych? (zakładając, że moje zatwierdzenia nie splątają się nawzajem). – user2097818

7

Można mieć Kolba-SQLAlchemy narażać własnego modelu podstawowego zamiast to wbudowany w jednym. Po prostu podklasę SQLAlchemy i przesuń make_declarative_base.

from flask.ext.sqlalchemy import SQLAlchemy 


class CustomAlchemy(SQLAlchemy): 
    def make_declarative_base(self): 
     base = declarative_base(...) 
     ... 
     return base 

db = CustomAlchemy() 
1

Używam sqlalchemy w kolbie bez użycia deklaratywnej bazy i nie mam żadnych problemów. Zawsze możesz to zrobić, jeśli chcesz, nie ma obowiązku używania obiektu odwzorowującego relacje obiektów, ORM to tylko jedna część sqlalchemy. Zawsze możesz pozostać przy alchemicznym języku wyrażenia sql, zdefiniować tabele w obiektach modelu i zdefiniować tam pewne metody, które będą używały języka wyrażeń. Mam taki kod (Model jest obiektem zdefiniowanym wcześniej), connect to dekorator, który łączy się z db, działa mi dobrze.

def connect(func): 
    eng = create_engine(app.config["DATABASE"]) 
    @wraps(func) 
    def wrapped(*args,**kwargs): 
     with closing(eng.connect()) as con: 
      result = con.execute(func(*args,**kwargs)) 
     return result 
    return wrapped 

class User_(Model): 
    def __init__(self): 
     Model.__init__(self) 
     self.metadata = MetaData() 
     self.structure = Table("users", self.metadata, 
           Column("id",Integer,primary_key=True), 
           Column("username",VARCHAR(64)), 
           Column("password",TEXT), 
           Column("email",VARCHAR(100)), 
           Column("about_me",TEXT), 
           Column("deadline",DATETIME), 
           Column("points",INTEGER)), 
           Column("date_created",DATETIME)) 

    @connect 
    def get_hashed_pass(self,username): 
     """ """ 
     t = self.structure 
     s = select([t.c.password]).where(t.c.username == str(username)) 
     return s 
#other methods follow 

Flask's documentation concerning alchemy wyraźnie mówi, że jest całkowicie w porządku, aby to zrobić:

Jeśli chcesz tylko do korzystania z systemu bazy danych (i SQL) warstwę abstrakcji w zasadzie trzeba silnik

tylko

PS Aha, i jeszcze jedno, mówią w dokumentach, że jeśli chcesz zacząć szybko, lepiej użyć rozszerzenia, ale osobiście nie jestem tego pewien, jeśli jesteś podobny do mnie i czujesz się bardziej znajomy przy zapytaniach sql zamiast w ORM może być znacznie łatwiejsze szybkie rozpoczęcie bez rozszerzenia.

+0

Zajęło mi trochę czasu, aby uzyskać swoje znaczenie (nie widziałem dekoratora connect na metodzie). Korzystanie z sesji wewnątrz modelu było moim następnym pytaniem! – user2097818

Powiązane problemy