我在我的python wsgi服务器上使用Flask,在我的数据库访问中使用sqlalchemy。
我想我想在我的应用程序中使用Flask-Sqlalchemy扩展,但我不想使用声明性基类(db.Model),相反,我想使用来自sqlalchemy.ext.declarative。
这是否会破坏使用扩展程序的全部目的?
我的用例:
我希望扩展程序可以帮助我更好地管理会话/引擎,但我想分别处理所有模型。
我实际上不介意使用扩展程序,但我想写严格模型。我正在从一个非烧瓶应用程序移植代码,我会在我去的时候将更改推回到该项目。例如,如果flask-sqlalchemy允许我在表元数据上作弊,那么当代码被推回时,这将导致问题。我的代码中还有一些代码可以进行大量的类型检查(多态身份),而且我还记得在使用扩展时不建议阅读Table上的类型检查。
答案 0 :(得分:7)
你可以让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()
答案 1 :(得分:1)
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
答案 2 :(得分:1)
我实际上在没有使用声明基础的情况下在烧瓶中使用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's documentation concerning alchemy明确表示完全可以这样做:
如果您只想使用数据库系统(和SQL)抽象层,基本上只需要引擎
P.S。哦,还有一件事,他们在文档中说,如果你想快速入门,你最好使用扩展,但我个人不太确定,如果你像我一样,你觉得更熟悉使用sql查询而不是使用ORM,您可以更轻松地在没有扩展的情况下快速入门。