dgilland / alchy Goto Github PK
View Code? Open in Web Editor NEWThe declarative companion to SQLAlchemy
Home Page: http://alchy.readthedocs.io
License: Other
The declarative companion to SQLAlchemy
Home Page: http://alchy.readthedocs.io
License: Other
http://docs.sqlalchemy.org/en/rel_0_9/orm/events.html
But allow an event decorator to function on class methods.
Something like:
class MyModel(Model):
@event('before_insert', 'before_update'):
def foo(...):
...
with automatic event registration.
In ModelBase, rename advanced_search_config
and simple_search_config
to __advanced_search__
and __simple_search__
respectively.
Hello
Thanks for the work. It makes integrating SqlAlchemy into a custom framework a snap.
I have an existing database with some database views. I want to reflect the database to map the tables and the views in a dictionary.
Would I follow the Flask pattern and subclass the Manager class and override the needed methods?
Thanks
Greg
FYI: pep8
is now pycodestyle
Details here: PyCQA/pycodestyle#466
In setting up a py.test session fixture, I ran into an issue where Alchy does not properly handle arguments passed from SQLAlchemy.
> session.add(model)
tests/test_models.py:17:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../.envs/platform/lib/python3.5/site-packages/sqlalchemy/orm/scoping.py:157: in do
return getattr(self.registry(), name)(*args, **kwargs)
../../../.envs/platform/lib/python3.5/site-packages/sqlalchemy/util/_collections.py:1025: in __call__
val = self.registry.value = self.createfunc()
../../../.envs/platform/lib/python3.5/site-packages/alchy/manager.py:241: in create_session
return self.session_class(self, **options)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <alchy.session.Session object at 0x10ddaf908>, manager = <alchy.manager.Manager object at 0x10c512f28>, options = {'binds': {}}, bind = <sqlalchemy.engine.base.Connection object at 0x10dda2a20>
def __init__(self, manager, **options):
self.manager = manager
bind = options.pop('bind', manager.engine)
super(Session, self).__init__(bind=bind,
binds=manager.binds_map,
> **options)
E TypeError: __init__() got multiple values for keyword argument 'binds'
../../../.envs/platform/lib/python3.5/site-packages/alchy/session.py:22: TypeError
The easy fix here is to update __init__
within the Session class to pop off the extraneous options. That said, I am not sure what the ramifications are of ignoring the binds
value. Therefore, my proposed solution is as follows:
def __init__(self, manager, **options):
self.manager = manager
bind = options.pop('bind', manager.engine)
binds = options.pop('binds', {}) or manager.binds_map
super(Session, self).__init__(bind=bind,
binds=binds,
**options)
Sometimes I use hybrid_property
or association_proxy
for many-to-many
relationships where I will prefix the base relationship with _<name>
and then have the hybrid or association defined as <name>
. When I call to_dict
, I generally want to exclude the _<name>
and only have <name>
. It may be useful to support a convention where any descriptor that begins with __
(double underscore) would be ignored by default when calling __to_dict__
/to_dict
.
Hi, I'm finding great use in this package to share code base between server and CLI!
However, I ran into an issue where I ended up in an endless loop of calls to to_dict
.
This is the affected code snippet:
def to_dict(self):
"""Return dict representation of model by filtering fields using
:attr:`__to_dict__`.
"""
data = {}
relationships = self.relationships()
for field in self.__to_dict__:
value = getattr(self, field)
# Nest calls to `to_dict`. Try to find method on base value,
# sequence values, or dict values.
if hasattr(value, 'to_dict'):
value = value.to_dict()
elif is_sequence(value):
value = [v.to_dict() if hasattr(v, 'to_dict') else v
for v in value]
elif isinstance(value, dict):
value = dict([(k, v.to_dict() if hasattr(v, 'to_dict') else v)
for k, v in iteritems(value)])
elif field in relationships and value is None:
value = {}
data[field] = value
return data
What I'm thinking might cause this to happen is the fact that if I have a relationship, say "parent" with a backref, "children" this loop will simply never end, no?
If a model has a relationship to a model with a backref, __to_dict__
will recursively try to display the relationship cycle.
In my own project I solved the problem by using a base inherited from ModelBase
that overrides __to_dict__
to skip relationships in recursing.
class Base(alchy.ModelBase):
# Alchy seems broken in its default to_dict implementation
# It appears to traverse relationships with multiple values, possibly causing
# an infinite recursion. E.g., users have questions and questions have users.
@property
def __to_dict__(self):
keys = super().__to_dict__
relationships = self.relationships()
return set(k for k in keys if k not in relationships)
I have some issue with handling postgresql restart.
I get the following error:
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) terminating connection due to administrator command
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
and my www app return 500.
when I repeat the same request I get:
Traceback (most recent call last):
File "/usr/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 1069, in _execute_context
conn = self.__connection
AttributeError: 'Connection' object has no attribute '_Connection__connection'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 1071, in _execute_context
conn = self._revalidate_connection()
File "/usr/lib/python3.3/site-packages/sqlalchemy/engine/base.py", line 391, in _revalidate_connection
"Can't reconnect until invalid "
sqlalchemy.exc.InvalidRequestError: Can't reconnect until invalid transaction is rolled back
@dgilland thanks for the very excellent blog post!
I have a question about this comment:
Just a heads up, in Flask-SQLAlchemy v3.0.0 (unreleased), they've added a "model_class" argument that will essentially make the recipe here unnecessary: https://github.com/mitsuhiko/flask-sqlalchemy/blob/7d65e2dc1f4e798f3234aaef01e615e3db319b05/flask_sqlalchemy/__init__.py#L728
You said that pallets-eco/flask-sqlalchemy#328 basically makes alchy
and Flask-Alchy
unnecessary, but after reading the long discussion at pallets-eco/flask-sqlalchemy#250, it sounds like there is more work to be done. Can you comment on how each of those pull requests relates to your blog post?
Thanks and sorry for the ignorance.
P.S. I also added a comment on the blog - feel free to respond to one or the other instead of both.
In ModelBase.update()
there is an argument to restrict updatable fields to Model.strict_update_fields
. By default, strict update is disabled when calling update()
and requires update(..., strict=True)
to enable. A configuration property should be available to make strict=True
the default. Something like ModelBase.__strict_update__ = False
and update(..., strict=None)
.
Add an upsert()
function which
dict
filter_by()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.