Использование Flask-SQLAlchemy без колбы
У меня была небольшая веб-служба, построенная с использованием Flask
и Flask-SQLAlchemy
, которая содержала только одну модель. Теперь я хочу использовать одну и ту же базу данных, но с помощью приложения с командной строкой, поэтому я хотел бы отказаться от зависимости Flask
.
Моя модель выглядит так:
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)
, как я могу преобразовать мою модель, чтобы использовать только SQLAlchemy. Есть ли способ для двух приложений (один с Flask-SQLAlchemy
другим с SQLAlchemy
) для использования одной и той же базы данных?
Ответы
Ответ 1
вы можете сделать это, чтобы заменить 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()
Ответ 2
В документации по sqlalchemy есть хороший учебник с примерами, которые звучат так, как вы хотите.
Показывает, как подключаться к БД, отображать, создавать схемы и запрашивать/сохранять в БД.
Ответ 3
Проверьте этот github.com/mardix/active-alchemy
Active-Alchemy - это агностическая оболочка для SQLAlchemy, которая делает ее очень простой в использовании, реализуя простую активную запись, например api, в то время как она все еще использует db.session под ней. Вдохновленный Flask-SQLAlchemy
Ответ 4
Flask (> 1.0) пытается предоставить помощники для обмена кодами между веб-приложением и интерфейсом командной строки; я лично думаю, что это может быть чище, легче и проще создавать библиотеки, не связанные с фляжкой, но вы можете проверить:
Ответ 5
Это не полностью отвечает на ваш вопрос, потому что он не удаляет зависимость от флэшей, но вы можете использовать SqlAlchemy
в сценариях и тестах, просто не используя приложение Flask.
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
Одна из трудностей, с которой вы можете столкнуться, - это требование использования 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()
Ответ 6
Существует отличная статья о Flask-SQLAlchemy: как это работает и как модифицировать модели для использования за пределами Flask:
http://derrickgilland.com/posts/demystifying-flask-sqlalchemy/
Ответ 7
Вот как использовать SQLAlchemy без Flask (например, для записи большого количества объектов в базу данных 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}'
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()
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()