Package: cone.sql
This package provides SQLAlchemy integration incone.appand basic
application nodes for publishing SQLAlchemy models.InstallationIncludecone.sqlto install dependencies in your application’ssetup.py.Configure Database and WSGIAdopt your application config ini file to define database location and hook
up the related elements to the WSGI pipeline.[app:my_app]use=egg:cone.app#mainpyramid.includes=pyramid_retrypyramid_tmtm.commit_veto=pyramid_tm.default_commit_vetocone.plugins=cone.sqlsql.db.url=sqlite:///%(here)s/var/sqlite/my_db.db[filter:remote_addr]# for use behind nginxuse=egg:cone.app#remote_addr[filter:session]use=egg:cone.sql#session[pipeline:main]pipeline=remote_addrsessionmy_appCreate Model and NodesDefine the SQLAlchemy model.fromcone.sqlimportSQLBasefromcone.sql.modelimportGUIDfromsqlalchemyimportColumnfromsqlalchemyimportStringclassMyRecord(SQLBase):__tablename__='my_table'uid_key=Column(GUID,primary_key=True)field=Column(String)Define an application node which represents the SQL row and uses the SQLAlchemy
model. The class holds a reference to the related SQLAlchemy model.fromcone.sql.modelimportSQLRowNodeclassMyNode(SQLRowNode):record_class=MyRecordDefine an application node which represents the table and acts as container for
the SQL row nodes. The class holds a reference to the related SQLAlchemy model
and the related SQLRowNode.fromcone.sql.modelimportSQLTableNodeclassMyContainer(SQLTableNode):record_class=MyRecordchild_factory=MyNodePrimary key handlingThe node name maps to the primary key of the SQLAlchemy model (currenly no
multiple primary keys are supported). Node names are converted to the
primary key data type automatically. The conversion factories are defined atSQLTableNode.data_type_converterswhich can be extended by more data types
if needed.>>>SQLTableNode.data_type_converters{<class'sqlalchemy.sql.sqltypes.String'>: <type 'unicode'>,<class'cone.sql.model.GUID'>: <class 'uuid.UUID'>,<class'sqlalchemy.sql.sqltypes.Integer'>: <type 'int'>}Integrate to the Application ModelIn order to publish a SQL table node, the table node must be hooked up to the
application model. To hook up the at root level, register it as entry.importcone.appcone.app.register_entry('container',MyContainer)Session setup handlersThere exists asql_session_setupdecorator which can be used to perform
session setup tasks like registering SQLAlchemy event listeners.fromcone.sqlimportsql_session_setupfromsqlalchemyimporteventdefafter_flush(session,flush_context):"""Do something after flush.
    """@sql_session_setupdefbind_session_listener(session):"""SQL session setup callback.
    """event.listen(session,'after_flush',after_flush)Query the databaseQuerying the database is done via SQLAlchemy. If you are in a request/response
cycle, you should acquire the session from request viaget_sessionand
perform arbitrary operations on it. By reading the session from request we ensure
the transaction manager to work properly if configured.fromcone.sqlimportget_sessionsession=get_session(request)result=session.query(MyRecord).all()If you need a session outside a request/response cycle you can create one by using
thesession_factory.fromcone.sqlimportsession_factorysession=session_factory()result=session.query(MyRecord).all()session.close()Principal ACL’sSQL based Principal ACL’s are implemented incone.sql.acl. The related
table gets created as soon as you import from this module.UsingSQLPrincipalACLrequires the model to implementnode.interfaces.IUUID.fromcone.sql.aclimportSQLPrincipalACLfromnode.baseimportBaseNodefromnode.interfacesimportIUUIDfromplumberimportplumbingfrompyramid.securityimportAllowfromzope.interfaceimportimplementerimportuuidasuuid_module@implementer(IUUID)@plumbing(SQLPrincipalACL)classSQLPrincipalACLNode(BaseNode):uuid=uuid_module.UUID('1a82fa87-08d6-4e48-8bc2-97ee5a52726d')@propertydef__acl__(self):return[(Allow,'role:editor',['edit']),(Allow,'role:manager',['manage']),]User and Group Managementcone.sql.ugmcontains an implementation of the UGM contracts defined atnode.ext.ugm.interfaces, using sql as backend storage:+------------+
                  |  Principal |
                  |(data: JSON)|
                  +------------+
                        ^
                        |
   +-----------------------------------------+
   |                                         |
   |                                         |
+------+                                 +-------+
| User |                                 | Group |
+------+                                 +-------+
    1                                        1
    |                                        |
    |                                        |
    +-------------+            +-------------+
                  |            |
                  n            m
                  |            |
               +-----------------+
               | GroupAssignment |
               +-----------------+Currently SQLite and PostgreSQL are supported and tested, other DBs must
be evaluated concerning their JSON capabilities since users and groups
store additional payload data in a JSON field which brings the flexibility
to store arbitrary data as a dict in the JSON field.To activate SQL based UGM backend, it needs to be configured via the application
ini config file.:ugm.backend=sqlsql.user_attrs=id, mail, fullname, portraitsql.group_attrs=descriptionsql.binary_attrs=portraitsql.log_auth=Truesql.user_expires_attr=expiresUGM users and groups are stored in the same database as defined atsql.db.urlin the config file.UGM dedicated config options:sql.user_attrsis a comma separated list of strings defining the
available user attributes stored in the user JSON data field.sql.group_attrsis a comma separated list of strings defining the
available group attributes stored in the group JSON data field.sql.binary_attrsis a comma separated list of strings defining the
attributes which are considered binary and get stored base 64 encoded in the
JSON data field of users and groups.sql.log_authdefaults to False. If set, the first login timestamp will
be stored during the first authentication and latest login timestamp will be
updated for each successful authentication.sql.user_expires_attrdefaults to None. If set, user expiration is
enabled and the value given is the attribute name of the JSON data field
where the expiration timestamp gets stored.Users and groups can be managed withcone.ugm. If activated,sql.user_attrsandsql.group_attrscan be omitted, relevant information
gets extracted from theugm.xmlconfig file.ugm.backend=sqlugm.config=%(here)s/ugm.xmlsql.log_auth=Truecone.plugins=cone.ugmcone.sqlTODOSupport multiple primary keys.ContributorsRobert Niederreiter (Author)Phil AuerspergChanges0.8 (2024-02-12)Initialize SQL before callingsetUpof super class inSQLLayer.setUp,
which itself callsmake_app. This ensuressql.session_factoryis
properly set if used in a conemain_hook.
[rnix]0.7 (2022-12-05)Implementexpiresandexpiredoncone.sql.ugm.UserBehavior.
Extendcone.sql.ugm.UgmBehaviorbyuser_expires_attrwhich
enables used expiration support.
[rnix]AddTestSQLSessionFactoryand set tocone.sql.session_factoryinSQLLayer.init_sqlif not present.
[rnix, toalba]0.6 (2022-10-06)Remove usage ofNodespacesbehavior.
[rnix]Replace deprecated use ofIStoragebyIMappingStorage.
[rnix]Replace deprecated use ofNodifybyMappingNode.
[rnix]Replace deprecated use ofAdoptbyMappingAdopt.
[rnix]Replace deprecated use ofNodeChildValidatebyMappingConstraints.
[rnix]Replace deprecated use ofallow_non_node_childrenbychild_constraints.
[rnix]0.5 (2021-11-08)Rename deprecatedSQLPrincipalRoles.allow_non_node_childstoallow_non_node_children[rnix]Addcache_oktoGUIDtype decorator to prevent warning with
SQLAlchemy 1.4
[rnix]0.4 (2020-11-12)Fix typo inSqlUGMFactory.__init__.
[rnix]0.3 (2020-07-09)SQL database URL setting key in ini file changed fromcone.sql.db.urltosql.db.url.
[rnix]Add SQL based UGM implementation.
[zworkb, rnix]Patchmakeroncone.sql.session_factoryif present incone.sql.testing.SQLLayerto ensure working session factory when running
tests.
[rnix]0.2 (2020-05-30)Introducecone.sql.SQLSessionFactory. Gets instanciated at application
startup as singleton atcone.sql.session_factory.
[rnix]SQL database URL setting key in ini file changed fromcone.sql.dbinit.urltocone.sql.db.url.
[rnix]SQL database URL definition is only required once in theappsection of
the ini file.sqlalchemy.urlcan be removed from session filter.
[rnix]Add SQL based principal ACL support.
[rnix]Python 3 compatibility.
[rnix]Fix hex formatting incone.sql.model.GUID.process_bind_param.
[rnix]Register SQL session to transaction manager withzope.sqlalchemy.register.
[rnix]Usepyramid_tminstead ofrepoze.tm2. Disabled by default, must be
enabled explicitely viapyramid.includes.
[rnix]Usepyramid_retryinstead ofrepoze.retry. Disabled by default, must be
enabled explicitely viapyramid.includes.
[rnix]Upgrade tocone.app1.0b1.
[rnix]0.1 (2017-03-28)Initial work.
[rnix]LicenseCopyright (c) 2017-2021, BlueDynamics Alliance, Austria
Copyright (c) 2021-2022, Cone Contributors
All rights reserved.Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.