Добавлена поддержка sqlite. Обновление до версии 0.3
parent
50f5a2210e
commit
348214e2e9
|
@ -39,6 +39,7 @@ pip-log.txt
|
|||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
.pytest_cache
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
|
5
Makefile
5
Makefile
|
@ -1,4 +1,7 @@
|
|||
all: bdist
|
||||
all: test bdist
|
||||
|
||||
bdist:
|
||||
python3 setup.py sdist bdist_wheel
|
||||
|
||||
test:
|
||||
pytest -q
|
||||
|
|
|
@ -64,6 +64,7 @@ def main(global_config, **settings):
|
|||
|
||||
config = Configurator(settings=settings,
|
||||
root_factory=factory)
|
||||
config.include('.models')
|
||||
config.include('pyramid_jinja2')
|
||||
config.include('.routes')
|
||||
config.scan()
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
from sqlalchemy import engine_from_config
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.orm import configure_mappers
|
||||
import zope.sqlalchemy
|
||||
|
||||
# import or define all models here to ensure they are attached to the
|
||||
# Base.metadata prior to any initialization routines
|
||||
from .pagemodel import PageModel # flake8: noqa
|
||||
|
||||
# run configure_mappers after defining all of the models to ensure
|
||||
# all relationships can be setup
|
||||
configure_mappers()
|
||||
|
||||
|
||||
def get_engine(settings, prefix='sqlalchemy.'):
|
||||
return engine_from_config(settings, prefix)
|
||||
|
||||
|
||||
def get_session_factory(engine):
|
||||
factory = sessionmaker()
|
||||
factory.configure(bind=engine)
|
||||
return factory
|
||||
|
||||
|
||||
def get_tm_session(session_factory, transaction_manager):
|
||||
"""
|
||||
Get a ``sqlalchemy.orm.Session`` instance backed by a transaction.
|
||||
|
||||
This function will hook the session to the transaction manager which
|
||||
will take care of committing any changes.
|
||||
|
||||
- When using pyramid_tm it will automatically be committed or aborted
|
||||
depending on whether an exception is raised.
|
||||
|
||||
- When using scripts you should wrap the session in a manager yourself.
|
||||
For example::
|
||||
|
||||
import transaction
|
||||
|
||||
engine = get_engine(settings)
|
||||
session_factory = get_session_factory(engine)
|
||||
with transaction.manager:
|
||||
dbsession = get_tm_session(session_factory, transaction.manager)
|
||||
|
||||
"""
|
||||
dbsession = session_factory()
|
||||
zope.sqlalchemy.register(
|
||||
dbsession, transaction_manager=transaction_manager)
|
||||
return dbsession
|
||||
|
||||
|
||||
def includeme(config):
|
||||
"""
|
||||
Initialize the model for a Pyramid app.
|
||||
|
||||
Activate this setup using ``config.include('db.models')``.
|
||||
|
||||
"""
|
||||
settings = config.get_settings()
|
||||
settings['tm.manager_hook'] = 'pyramid_tm.explicit_manager'
|
||||
|
||||
# use pyramid_tm to hook the transaction lifecycle to the request
|
||||
config.include('pyramid_tm')
|
||||
|
||||
# use pyramid_retry to retry a request when transient exceptions occur
|
||||
config.include('pyramid_retry')
|
||||
|
||||
session_factory = get_session_factory(get_engine(settings))
|
||||
config.registry['dbsession_factory'] = session_factory
|
||||
|
||||
# make request.dbsession available for use in Pyramid
|
||||
config.add_request_method(
|
||||
# r.tm is the transaction manager used by pyramid_tm
|
||||
lambda r: get_tm_session(session_factory, r.tm),
|
||||
'dbsession',
|
||||
reify=True
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.schema import MetaData
|
||||
|
||||
# Recommended naming convention used by Alembic, as various different database
|
||||
# providers will autogenerate vastly different names making migrations more
|
||||
# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html
|
||||
NAMING_CONVENTION = {
|
||||
"ix": "ix_%(column_0_label)s",
|
||||
"uq": "uq_%(table_name)s_%(column_0_name)s",
|
||||
"ck": "ck_%(table_name)s_%(constraint_name)s",
|
||||
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
|
||||
"pk": "pk_%(table_name)s"
|
||||
}
|
||||
|
||||
metadata = MetaData(naming_convention=NAMING_CONVENTION)
|
||||
Base = declarative_base(metadata=metadata)
|
|
@ -0,0 +1,17 @@
|
|||
from sqlalchemy import (
|
||||
Column,
|
||||
Index,
|
||||
String,
|
||||
Text,
|
||||
)
|
||||
|
||||
from .meta import Base
|
||||
|
||||
|
||||
class PageModel(Base):
|
||||
__tablename__ = 'pages'
|
||||
url = Column(String(2000), primary_key=True)
|
||||
title = Column(Text)
|
||||
|
||||
|
||||
Index('page_index', PageModel.url, unique=True, mysql_length=255)
|
|
@ -0,0 +1,13 @@
|
|||
from . import models
|
||||
|
||||
|
||||
def setup(env):
|
||||
request = env['request']
|
||||
|
||||
# start a transaction
|
||||
request.tm.begin()
|
||||
|
||||
# inject some vars into the shell builtins
|
||||
env['tm'] = request.tm
|
||||
env['dbsession'] = request.dbsession
|
||||
env['models'] = models
|
|
@ -0,0 +1,66 @@
|
|||
import unittest
|
||||
|
||||
from pyramid import testing
|
||||
|
||||
import transaction
|
||||
|
||||
|
||||
def dummy_request(dbsession):
|
||||
return testing.DummyRequest(dbsession=dbsession)
|
||||
|
||||
|
||||
class BaseTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.config = testing.setUp(settings={
|
||||
'sqlalchemy.url': 'sqlite:///:memory:'
|
||||
})
|
||||
self.config.include('.models')
|
||||
settings = self.config.get_settings()
|
||||
|
||||
from .models import (
|
||||
get_engine,
|
||||
get_session_factory,
|
||||
get_tm_session,
|
||||
)
|
||||
|
||||
self.engine = get_engine(settings)
|
||||
session_factory = get_session_factory(self.engine)
|
||||
|
||||
self.session = get_tm_session(session_factory, transaction.manager)
|
||||
|
||||
def init_database(self):
|
||||
from .models.meta import Base
|
||||
Base.metadata.create_all(self.engine)
|
||||
|
||||
def tearDown(self):
|
||||
from .models.meta import Base
|
||||
|
||||
testing.tearDown()
|
||||
transaction.abort()
|
||||
Base.metadata.drop_all(self.engine)
|
||||
|
||||
|
||||
# class TestMyViewSuccessCondition(BaseTest):
|
||||
|
||||
# def setUp(self):
|
||||
# super(TestMyViewSuccessCondition, self).setUp()
|
||||
# self.init_database()
|
||||
|
||||
# from .models import PageModel
|
||||
|
||||
# model = PageModel(name='one', value=55)
|
||||
# self.session.add(model)
|
||||
|
||||
# def test_passing_view(self):
|
||||
# from .views.default import my_view
|
||||
# info = my_view(dummy_request(self.session))
|
||||
# self.assertEqual(info['one'].name, 'one')
|
||||
# self.assertEqual(info['project'], 'db')
|
||||
|
||||
|
||||
# class TestMyViewFailureCondition(BaseTest):
|
||||
|
||||
# def test_failing_view(self):
|
||||
# from .views.default import my_view
|
||||
# info = my_view(dummy_request(self.session))
|
||||
# self.assertEqual(info.status_int, 500)
|
|
@ -0,0 +1,3 @@
|
|||
[pytest]
|
||||
testpaths = flatfilecms
|
||||
python_files = test*.py
|
10
setup.py
10
setup.py
|
@ -11,12 +11,14 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
|
|||
requires = [
|
||||
'plaster_pastedeploy',
|
||||
'pyramid >= 1.10',
|
||||
'pyramid_debugtoolbar',
|
||||
'pyramid_jinja2',
|
||||
'pyramid_debugtoolbar',
|
||||
'waitress',
|
||||
'pyramid_retry',
|
||||
'pyramid_tm',
|
||||
'SQLAlchemy',
|
||||
'transaction',
|
||||
'waitress',
|
||||
'zope.sqlalchemy',
|
||||
'Markdown',
|
||||
'PyYAML',
|
||||
'python-frontmatter',
|
||||
|
@ -27,13 +29,13 @@ requires = [
|
|||
|
||||
tests_require = [
|
||||
'WebTest >= 1.3.1', # py3 compat
|
||||
'pytest',
|
||||
'pytest >= 3.7.4',
|
||||
'pytest-cov',
|
||||
]
|
||||
|
||||
setup(
|
||||
name='flatfilecms',
|
||||
version='0.2',
|
||||
version='0.3',
|
||||
description='flat-file CMS suitable for static site',
|
||||
long_description=README + '\n\n' + CHANGES,
|
||||
classifiers=[
|
||||
|
|
Reference in New Issue