簡體   English   中英

使用flask-sqlalchemy而沒有子類聲明基礎

[英]using flask-sqlalchemy without the subclassed declarative base

我正在使用Flask作為我的python wsgi服務器,而sqlalchemy使用我的所有數據庫訪問。

我想在我的應用程序中使用Flask-Sqlalchemy擴展,但我不想使用聲明性基類(db.Model),而是想要使用sqlalchemy.ext.declarative中的基類。

這是否會破壞使用擴展程序的全部目的?


我的用例:

我想擴展程序可以幫助我更好地管理會話/引擎,但我想分別處理所有模型。

我實際上不介意使用擴展,但我想編寫嚴格的模型。 我正在從一個非燒瓶應用程序移植代碼,我會在我去的時候將更改推回到該項目。 例如,如果flask-sqlalchemy允許我欺騙表元數據 ,那么當代碼被推回時會導致問題。 我的代碼中還有一些代碼可以進行大量的類型檢查(多態身份),我還記得在使用擴展時不建議讀取表格上的類型檢查。

你可以讓Flask-SQLAlchemy公開你自己的基礎模型而不是它的內置模型。 只需將SQLAlchemy子類化並覆蓋make_declarative_base

from flask.ext.sqlalchemy import SQLAlchemy


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

db = CustomAlchemy()

SQLAlchemy本身實際上建議您使用Flask包裝器(db.Model)進行Flask項目。 話雖如此,我在我的幾個Flask項目中使用了declarative_base模型,它更有意義。

它確實從flask-sqlalchemy中擊敗了SQLAlchemy類的整個目的。

這是一些示例代碼:

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

我實際上在沒有使用聲明基礎的情況下在燒瓶中使用sqlalchemy而且我沒有任何問題。 如果你願意,你總是可以這樣做,沒有義務使用對象關系映射器,ORM只是sqlalchemy的一部分。 您可以隨時使用alchemy sql表達式語言,在模型對象中定義表,並在那里定義一些將使用表達式語言的方法。 我有這樣的代碼(模型是我之前定義的對象),connect是連接到db的裝飾器,它對我來說很好。

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關於煉金術的文件明確表示完全可以這樣做:

如果您只想使用數據庫系統(和SQL)抽象層,則基本上只需要引擎

PS哦,還有一件事,他們在文檔中說,如果你想快速入門,你最好使用擴展,但我個人不太確定,如果你像我一樣,你感覺更多熟悉sql查詢而不是ORM,你可以更容易地在沒有擴展的情況下快速入門。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM