[英]Using Flask-SQLAlchemy without Flask
我有一个使用Flask
和Flask-SQLAlchemy
构建的小型 web 服务,它只包含一个 model。我现在想使用相同的数据库,但使用命令行应用程序,所以我想删除Flask
依赖项。
我的 model 看起来像这样:
class IPEntry(db.Model):
id = db.Column(db.Integer, primary_key=True)
ip_address = db.Column(db.String(16), unique=True)
first_seen = db.Column(db.DateTime(),
default = datetime.datetime.utcnow
)
last_seen = db.Column(db.DateTime(),
default = datetime.datetime.utcnow
)
@validates('ip')
def validate_ip(self, key, ip):
assert is_ip_addr(ip)
return ip
由于db
将不再是对flask.ext.sqlalchemy.SQLAlchemy(app)
的引用,我如何将我的 model 转换为仅使用 SQLAlchemy。这两个应用程序有没有办法(一个使用Flask-SQLAlchemy
,另一个使用SQLAlchemy
)8494使用相同的数据库?
你可以这样做来替换db.Model
:
from sqlalchemy import orm
from sqlalchemy.ext.declarative import declarative_base
import sqlalchemy as sa
base = declarative_base()
engine = sa.create_engine(YOUR_DB_URI)
base.metadata.bind = engine
session = orm.scoped_session(orm.sessionmaker())(bind=engine)
# after this:
# base == db.Model
# session == db.session
# other db.* values are in sa.*
# ie: old: db.Column(db.Integer,db.ForeignKey('s.id'))
# new: sa.Column(sa.Integer,sa.ForeignKey('s.id'))
# except relationship, and backref, those are in orm
# ie: orm.relationship, orm.backref
# so to define a simple model
class UserModel(base):
__tablename__ = 'users' #<- must declare name for db table
id = sa.Column(sa.Integer,primary_key=True)
name = sa.Column(sa.String(255),nullable=False)
然后创建表:
base.metadata.create_all()
检查这个github.com/mardix/active-alchemy
Active-Alchemy 是 SQLAlchemy 的框架无关包装器,它通过实现一个简单的活动记录(如 api)使其非常易于使用,同时它仍然使用下面的 db.session。 受 Flask-SQLAlchemy 的启发
这就是如何在没有 Flask 的情况下使用 SQLAlchemy(例如将大量对象写入 PostgreSQL 数据库):
from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# Define variables DB_USERNAME, DB_PASSWORD, DB_HOST, DB_PORT, DB_NAME
SQLALCHEMY_DATABASE_URI = f'postgresql://{DB_USERNAME}:{DB_PASSWORD}@{DB_HOST}:
{DB_PORT}/{DB_NAME}'
# ----- This is related code -----
engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)
Base = declarative_base()
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
Session.configure(bind=engine)
session = Session()
# ----- This is related code -----
class MyModel(Base):
__tablename__ = 'my_table_name'
id = Column(Integer, primary_key=True)
value = Column(String)
objects = [MyModel(id=0, value='a'), MyModel(id=1, value='b')]
session.bulk_save_objects(objects)
session.commit()
sqlalchemy docs 有一个很好的教程,里面的例子听起来像你想要做的。
展示如何连接到数据库、映射、模式创建以及查询/保存到数据库。
有一篇关于 Flask-SQLAlchemy 的很棒的文章:它是如何工作的,以及如何修改模型以在 Flask 之外使用它们:
http://derrickgilland.com/posts/demystifying-flask-sqlalchemy/
Flask (> 1.0) 尝试提供帮助器以在 Web 应用程序和命令行界面之间共享代码; 我个人认为构建未绑定到烧瓶的库可能更干净、更轻、更容易,但您可能需要检查:
这并不能完全回答您的问题,因为它不会删除 Flask 依赖项,但是您可以通过不运行Flask 应用程序在脚本和测试中使用SqlAlchemy
。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import MetaData
test_app = Flask('test_app')
test_app.config['SQLALCHEMY_DATABASE_URI'] = 'database_uri'
test_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
metadata = MetaData(schema='myschema')
db = SQLAlchemy(test_app, metadata=metadata)
class IPEntry(db.Model):
pass
您可能会遇到的一个困难是,如果您想使用相同的代码库来定位 Web 应用程序和独立脚本,则需要使用db.Model
作为模型的基类。 解决它的可能方法是使用动态多态并将类定义包装在一个函数中。
def get_ipentry(db):
class IPEntry(db.Model):
pass
return IPEntry
当您在函数中构造类运行时,您可以传入不同的SqlAlchemy
实例。 唯一的缺点是在使用之前需要调用函数来构造类。
db = SqlAlchemy(...)
IpEntry = get_ipentry(db)
IpEntry.query.filter_by(id=123).one()
import os
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
if os.path.exists('test.db'):
os.remove('test.db')
Base = declarative_base()
class Person(Base):
__tablename__ = 'person'
id = Column(Integer(), primary_key=True)
name = Column(String())
engine = create_engine('sqlite:///test.db')
Base.metadata.create_all(engine)
from flask import Flask
from sqlalchemy import MetaData
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app, metadata=MetaData())
class Person(db.Model):
__tablename__ = 'person'
id = Column(Integer(), primary_key=True)
name = Column(String())
person = Person(name='Bob')
db.session.add(person)
db.session.commit()
print(person.id)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.