A friendly wrapper for modern SQLAlchemy and Alembic

Overview

SQLA-Wrapper

A friendly wrapper for modern SQLAlchemy (v1.4 or later) and Alembic.

Documentation: https://jpsca.github.io/sqla-wrapper/

Includes:

  • A SQLAlchemy wrapper, that does all the SQLAlchemy setup and gives you:

    • A preconfigured scoped session.
    • A model baseclass including some helper methods.
    • A helper for performant testing with a real database
  • An Alembic wrapper that loads the config from your application instead of an ini file.

  • A sa helper module, that imports all the functions and classes from sqlalchemyand sqlalchemy.orm, so you don't need to repeat those imports everywhere.

Comments
  • Allow to change engine and session configuration after init

    Allow to change engine and session configuration after init

    It may be useful for unit tests. Short example for py.test:

    @pytest.fixture(scope='function', autouse=True)
    def clean_up_db():
        # called before all test functions
        db.reconfigure(uri='sqlite://', echo=True)
        db.drop_all()
        db.create_all()
    
    def test_something():
        db.add(Item())
        db.commit()
        ...
    

    Also related to #24 cause we can not read Flask-SQLAlchemy's app.config

    opened by vsurjaninov 4
  • Inheritance does not work properly

    Inheritance does not work properly

    Because db.Model explicitly defines __tablename__, STI doesn't work since the declarative_base expects __tablename__ to be undefined to work properly.

    http://docs.sqlalchemy.org/en/rel_1_0/orm/inheritance.html?highlight=inheritance#single-table-inheritance

    flask-sqlalchemy actually had the same problem at one point and they fixed this by checking to see whether the table name should actually be set in different instances: https://github.com/mitsuhiko/flask-sqlalchemy/blob/master/flask_sqlalchemy/init.py#L553-L591

    opened by jcn 3
  • "verbose" argument to alembic.history cli command

    without this parameter command actually doesn't work:

     python manage.py db history
    Traceback (most recent call last):
      File "manage.py", line 41, in <module>
        cli()
      File "/home/krnr/.pyenv/versions/ard38/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
        return self.main(*args, **kwargs)
      File "/home/krnr/.pyenv/versions/ard38/lib/python3.8/site-packages/click/core.py", line 1055, in main
        rv = self.invoke(ctx)
      File "/home/krnr/.pyenv/versions/ard38/lib/python3.8/site-packages/click/core.py", line 1657, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/home/krnr/.pyenv/versions/ard38/lib/python3.8/site-packages/click/core.py", line 1657, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/home/krnr/.pyenv/versions/ard38/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/home/krnr/.pyenv/versions/ard38/lib/python3.8/site-packages/click/core.py", line 760, in invoke
        return __callback(*args, **kwargs)
      File "/home/krnr/.pyenv/versions/ard38/lib/python3.8/site-packages/sqla_wrapper/cli/click_cli.py", line 71, in history
        alembic.history(verbose, start=start, end=end)
    TypeError: history() takes 1 positional argument but 2 positional arguments (and 2 keyword-only arguments) were given
    
    opened by krnr 2
  • Two Pypi (pip) packages

    Two Pypi (pip) packages

    Hi!

    There are two Pypi packages for this project:

    The latter is probably the correct one (or the latest one), but having two pip packages can confuse users. Please either delete the SQLAlchemy-Wrapper package or add a notice in the README.md file to install sqla-wrapper.

    Usually readme files start with installation instructions: pip install sqla-wrapper. This makes it clear which package to install.

    opened by ramuta 2
  • Flask debug toolbar doesnt show queries(shows unavailable)

    Flask debug toolbar doesnt show queries(shows unavailable)

    As i am trying to make the "transition" from Flask-SQLAlchemy to your fork i found this problem where the debug toolbar doesnt show information about the queries, it just tells me that i have to install Flask-SQLAlachemy.

    I saw a commit about supporting the toolbar in your fork but im not expert to debug what is wrong cause maybe im missing something.

    # __init__.py
    from flask import Flask
    from sqlalchemy_wrapper import SQLAlchemy
    from flask.ext.bcrypt import Bcrypt
    
    app = Flask(__name__, instance_relative_config=True, static_url_path='')
    bcrypt = Bcrypt(app)
    
    app.config.from_pyfile('development.py')
    
    db = SQLAlchemy(app.config['SQLALCHEMY_DATABASE_URI'], app=app)
    
    
    # run.py
    from flask_debugtoolbar import DebugToolbarExtension
    toolbar = DebugToolbarExtension()
    toolbar.init_app(app)
    
    opened by ev-agelos 2
  • UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 63: ordinal not in range(128)

    UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 63: ordinal not in range(128)

    Orignal Query -

    data = db.session.query(PublishEvent, ImageLicense).join(PublishEvent.images).join(ImageLicense).filter(ImageLicense.licensed_at != None')
    

    Traceback -

    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/core/displayhook.pyc in __call__(self, result)
        245             self.start_displayhook()
        246             self.write_output_prompt()
    --> 247             format_dict, md_dict = self.compute_format_data(result)
        248             self.write_format_data(format_dict, md_dict)
        249             self.update_user_ns(result)
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/core/displayhook.pyc in compute_format_data(self, result)
        155
        156         """
    --> 157         return self.shell.display_formatter.format(result)
        158
        159     def write_format_data(self, format_dict, md_dict=None):
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/core/formatters.pyc in format(self, obj, include, exclude)
        150             md = None
        151             try:
    --> 152                 data = formatter(obj)
        153             except:
        154                 # FIXME: log the exception
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/core/formatters.pyc in __call__(self, obj)
        479                 type_pprinters=self.type_printers,
        480                 deferred_pprinters=self.deferred_printers)
    --> 481             printer.pretty(obj)
        482             printer.flush()
        483             return stream.getvalue()
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/lib/pretty.pyc in pretty(self, obj)
        345                 if cls in self.type_pprinters:
        346                     # printer registered in self.type_pprinters
    --> 347                     return self.type_pprinters[cls](obj, self, cycle)
        348                 else:
        349                     # deferred printer
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/lib/pretty.pyc in inner(obj, p, cycle)
        529                 p.text(',')
        530                 p.breakable()
    --> 531             p.pretty(x)
        532         if len(obj) == 1 and type(obj) is tuple:
        533             # Special case for 1-item tuples.
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/lib/pretty.pyc in pretty(self, obj)
        345                 if cls in self.type_pprinters:
        346                     # printer registered in self.type_pprinters
    --> 347                     return self.type_pprinters[cls](obj, self, cycle)
        348                 else:
        349                     # deferred printer
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/lib/pretty.pyc in inner(obj, p, cycle)
        529                 p.text(',')
        530                 p.breakable()
    --> 531             p.pretty(x)
        532         if len(obj) == 1 and type(obj) is tuple:
        533             # Special case for 1-item tuples.
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/lib/pretty.pyc in pretty(self, obj)
        360                             if callable(meth):
        361                                 return meth(obj, self, cycle)
    --> 362             return _default_pprint(obj, self, cycle)
        363         finally:
        364             self.end_group()
    
    /Users/newscred/.virtualenvs/nc-reporting/lib/python2.7/site-packages/IPython/lib/pretty.pyc in _default_pprint(obj, p, cycle)
        480     if getattr(klass, '__repr__', None) not in _baseclass_reprs:
        481         # A user-provided repr.
    --> 482         p.text(repr(obj))
        483         return
        484     p.begin_group(1, '<')
    
    UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 63: ordinal not in range(128)
    
    opened by pranto157 2
  • default extend_existing to True

    default extend_existing to True

    In model.py after cls.__tablename__ = _get_table_name(cls.__name__), would you consider adding cls.__table_args__ = {'extend_existing':True}?

    It allows to change the model interactively, e.g. in IPython.

    opened by rpuntaie 1
  • installation instructions

    installation instructions

    From this issue: https://github.com/jpscaletti/sqla-wrapper/issues/31

    There are two Pypi packages for this project:

    The latter is probably the correct one (or the latest one), but having two pip packages can confuse users.

    I added installation instructions now to make it clear which package needs to be installed.

    opened by ramuta 1
  • User.query AttributeError

    User.query AttributeError

    https://github.com/jpscaletti/sqla-wrapper/blob/master/docs/quickstart.rst#simple-relationships Quickstart provides example:

    users = User.query.all()
    

    but actually I am getting error: AttributeError: type object 'User' has no attribute 'query'

    Type:Enhancement Status:🤔 
    opened by kiddten 1
  • create_engine() falls with mysql and something pool classes

    create_engine() falls with mysql and something pool classes

    Hello!

    Something pool classes such as NullPool, StaticPool not supports 'pool_size' argument. Following code produces an error:

    SQLAlchemy('mysql://...', poolclass=NullPool)

    TypeError: Invalid argument(s) 'pool_size' sent to create_engine(), using configuration MySQLDialect_mysqldb/NullPool/Engine. Please check that the keyword arguments are appropriate for this combination of components.

    My patch checks arguments of pool class __init__ function for fix it. That's little dirty, but removing problem part from apply_driver_hacks may produce unexpected consequences.

    opened by vsurjaninov 1
  • add

    add "poolclass" parameter

    Hello! I want to allow passing "poolclass" parameter to create_engine() . In my project I have to patching or subclassing original SQLAlchemy class for change it.

    Also flask-sqlachemy has the same issue: https://github.com/mitsuhiko/flask-sqlalchemy/issues/266

    opened by vsurjaninov 1
Releases(v5.6.1)
  • v5.6.1(May 26, 2022)

    What's Changed

    • "verbose" argument to alembic.history cli command by @krnr in https://github.com/jpsca/sqla-wrapper/pull/40

    New Contributors

    • @krnr made their first contribution in https://github.com/jpsca/sqla-wrapper/pull/40

    Full Changelog: https://github.com/jpsca/sqla-wrapper/compare/v5.4...v5.6.1

    Source code(tar.gz)
    Source code(zip)
  • v5.4(Jan 31, 2022)

  • v5.3(Jan 31, 2022)

  • v5.2(Jan 2, 2022)

  • v5.1(Oct 19, 2021)

  • v5.0.0(Oct 19, 2021)

    A new beginning...

    This version is a complete rewrite of the library and the documentation. From now on, only the new SQLAlchemy API (v1.4+) will be supported.

    SQLA-wrapper now includes:

    1. A wrapper for SQLAlchemy that does all the setup and gives you:
    • A session class and a scoped session, both extended with some useful active-record-like methods and pagination.
    • A declarative base class.
    • A helper for performant testing with a real database.
    1. A new Alembic wrapper that loads the config from your application instead of from separated alembic.ini and env.py files.
    • CLI integrations with click and pyCEO.
    Source code(tar.gz)
    Source code(zip)
Owner
Juan-Pablo Scaletti
JP spends most of his days trying to convince computers to do things.
Juan-Pablo Scaletti
Turn any OpenAPI2/3 and Postman Collection file into an API server with mocking, transformations and validations.

Prism is a set of packages for API mocking and contract testing with OpenAPI v2 (formerly known as Swagger) and OpenAPI v3.x. Mock Servers: Life-like

Stoplight 3.3k Jan 05, 2023
pytest plugin for a better developer experience when working with the PyTorch test suite

pytest-pytorch What is it? pytest-pytorch is a lightweight pytest-plugin that enhances the developer experience when working with the PyTorch test sui

Quansight 39 Nov 18, 2022
This is a bot that can type without any assistance and have incredible speed.

BulldozerType This is a bot that can type without any assistance and have incredible speed. This bot currently only works on the site https://onlinety

1 Jan 03, 2022
Mock smart contracts for writing Ethereum test suites

Mock smart contracts for writing Ethereum test suites This package contains comm

Trading Strategy 222 Jan 04, 2023
自动化爬取并自动测试所有swagger-ui.html显示的接口

swagger-hack 在测试中偶尔会碰到swagger泄露 常见的泄露如图: 有的泄露接口特别多,每一个都手动去试根本试不过来 于是用python写了个脚本自动爬取所有接口,配置好传参发包访问 原理是首先抓取http://url/swagger-resources 获取到有哪些标准及对应的文档地

jayus 534 Dec 29, 2022
The successor to nose, based on unittest2

Welcome to nose2 nose2 is the successor to nose. It's unittest with plugins. nose2 is a new project and does not support all of the features of nose.

736 Dec 16, 2022
Test utility for validating OpenAPI documentation

DRF OpenAPI Tester This is a test utility to validate DRF Test Responses against OpenAPI 2 and 3 schema. It has built-in support for: OpenAPI 2/3 yaml

snok 103 Dec 21, 2022
A pytest plugin to skip `@pytest.mark.slow` tests by default.

pytest-skip-slow A pytest plugin to skip @pytest.mark.slow tests by default. Include the slow tests with --slow. Installation $ pip install pytest-ski

Brian Okken 19 Jan 04, 2023
Show coverage stats online via coveralls.io

Coveralls for Python Test Status: Version Info: Compatibility: Misc: coveralls.io is a service for publishing your coverage stats online. This package

Kevin James 499 Dec 28, 2022
Webscreener is a tool for mass web domains pentesting.

Webscreener is a tool for mass web domains pentesting. It is used to take snapshots for domains that is generated by a tool like knockpy or Sublist3r. It cuts out most of the pentesting time by scree

Seekurity 3 Jun 07, 2021
Python program that uses pynput to simulate key presses. Probably only works on Windows.

AutoKey Python program that uses pynput to simulate key presses. Probably only works on Windows. Can be used for pretty much whatever you want except

2 Oct 28, 2022
A testing system for catching visual regressions in Web applications.

Huxley Watches you browse, takes screenshots, tells you when they change Huxley is a test-like system for catching visual regressions in Web applicati

Facebook Archive 4.1k Nov 30, 2022
This project demonstrates selenium's ability to extract files from a website.

This project demonstrates selenium's ability to extract files from a website. I've added the challenge of connecting over TOR. This package also includes a personal archive site built in NodeJS and A

2 Jan 16, 2022
Let your Python tests travel through time

FreezeGun: Let your Python tests travel through time FreezeGun is a library that allows your Python tests to travel through time by mocking the dateti

Steve Pulec 3.5k Dec 29, 2022
User-oriented Web UI browser tests in Python

Selene - User-oriented Web UI browser tests in Python (Selenide port) Main features: User-oriented API for Selenium Webdriver (code like speak common

Iakiv Kramarenko 575 Jan 02, 2023
pytest splinter and selenium integration for anyone interested in browser interaction in tests

Splinter plugin for the pytest runner Install pytest-splinter pip install pytest-splinter Features The plugin provides a set of fixtures to use splin

pytest-dev 238 Nov 14, 2022
Doing dirty (but extremely useful) things with equals.

Doing dirty (but extremely useful) things with equals. Documentation: dirty-equals.helpmanual.io Source Code: github.com/samuelcolvin/dirty-equals dir

Samuel Colvin 602 Jan 05, 2023
Data App Performance Tests

Data App Performance Tests My hypothesis is that The different architectures of

Marc Skov Madsen 6 Dec 14, 2022
Testinfra test your infrastructures

Testinfra test your infrastructure Latest documentation: https://testinfra.readthedocs.io/en/latest About With Testinfra you can write unit tests in P

pytest-dev 2.1k Jan 07, 2023
Command line driven CI frontend and development task automation tool.

tox automation project Command line driven CI frontend and development task automation tool At its core tox provides a convenient way to run arbitrary

tox development team 3.1k Jan 04, 2023