In SqlAlchemy how can I configure ALL relationship()s to use a loading strategy by default? - sqlalchemy

The default SqlAlchemy relationship loading strategy is lazy. If I want to change that to some other default, how would I do that?
I thought I saw it in the docs somewhere but I am not able to find it again. Maybe I didn't see such a thing?
I suppose one way would be to write my own relationship() method that calls SqlAlchemy's relationship method but sets lazy to some other default if it's None, but is there a built-in way to do this?

There isn't a way to globally change the default argument to relationship.lazy.
You can use functools.partial:
from functools import partial
from sqlalchemy.orm import relationship
relationship = partial(relationship, lazy='joined')
You can later override the lazy parameter like so:
class User:
...
things = relationship('Thing', lazy='select')

Related

SQLAlchemy - add mixin class to Automaped classes

I'm using SQLAlchemy and am generating classes dynamically for my database via the Automapping functionality.
I need to add a Mixin class with various helper methods to each of these automapped classes.
I tried to create subclasses of the automapped class with the mixin class:
db = create_engine(connection_string)
automapper = automap_base()
automapper.prepare(db, reflect=True)
for class_variable in automapper.__subclasses__():
new_class = type(class_variable.__name__, (class_variable, Mixins), {})
when I try to use these classes I get errors like:
class _ is a subclass of AutomapBase. Mappings are not produced until the .prepare() method is called on the class hierarchy.
If I call automapper.prepare() again, I get warnings like this and mostly just enters an infinite loop:
SAWarning: This declarative base already contains a class with the same class name and module name as sqlalchemy.ext.automap.payments, and will be replaced in the string-lookup table.
I cannot specify the classes explicitly as in this answer, because I don't know the database tables ahead of time.
From the docs, you can augment the Base with your Mixin class. In this case, you could pass your Mixin as the cls parameter.
automapper = automap_base(cls=Mixin)

Why does a function name have to be specified in a use statement?

In perl, sometimes it is necessary to specify the function name in the use statement.
For example:
use Data::DPath ('dpath');
will work but
use Data::DPath;
won't.
Other modules don't need the function names specified, for example:
use WWW::Mechanize;
Why?
Each module chooses what functions it exports by default. Some choose to export no functions by default at all, you have to ask for them. There's a few good reasons to do this, and one bad one.
If you're a class like WWW::Mechanize, then you don't need to export any functions. Everything is a class or object method. my $mech = WWW::Mechanize->new.
If you're a pragma like strict then there are no functions nor methods, it does its work simply by being loaded.
Some modules export waaay too many functions by default. An example is Test::Deep which exports...
all any array array_each arrayelementsonly arraylength arraylengthonly bag blessed bool cmp_bag cmp_deeply cmp_methods cmp_set code eq_deeply hash
hash_each hashkeys hashkeysonly ignore Isa isa listmethods methods noclass
none noneof num obj_isa re reftype regexpmatches regexponly regexpref
regexprefonly scalarrefonly scalref set shallow str subbagof subhashof
subsetof superbagof superhashof supersetof useclass
The problem comes when another module tries to export the same functions, or if you write a function with the same name. Then they clash and you get mysterious warnings.
$ cat ~/tmp/test.plx
use Test::Deep;
use List::Util qw(all);
$ perl -w ~/tmp/test.plx
Subroutine main::all redefined at /Users/schwern/perl5/perlbrew/perls/perl-5.20.2/lib/5.20.2/Exporter.pm line 66.
at /Users/schwern/tmp/test.plx line 2.
Prototype mismatch: sub main::all: none vs (&#) at /Users/schwern/perl5/perlbrew/perls/perl-5.20.2/lib/5.20.2/Exporter.pm line 66.
at /Users/schwern/tmp/test.plx line 2.
For this reason, exporting lots of functions is discouraged. For example, the Exporter documentation advises...
Do not export method names!
Do not export anything else by default without a good reason!
Exports pollute the namespace of the module user. If you must export try to use #EXPORT_OK in preference to #EXPORT and avoid short or common symbol names to reduce the risk of name clashes.
Unfortunately, some modules take this too far. Data::DPath is a good example. It has a really clear main function, dpath(), which it should export by default. Otherwise it's basically useless.
You can always turn off exporting with use Some::Module ();.
The reason is that some modules simply contain functions in them and they may or may not have chosen to export them by default, and that means they may need to be explicitly imported by the script to access directly or use a fully qualified name to access them. For example:
# in some script
use SomeModule;
# ...
SomeModule::some_function(...);
or
use SomeModule ('some_function');
# ...
some_function(...);
This can be the case if the module was not intended to be used in an object-oriented way, i.e. where no classes have been defined and lines such as my $obj = SomeModule->new() wouldn't work.
If the module has defined content in the EXPORT_OK array, it means that the client code will only get access to it if it "asks for it", rather than "automatically" when it's actually present in the EXPORT array.
Some modules automatically export their content by means of the #EXPORT array. This question and the Exporter docs have more detail on this.
Without you actually posting an MCVE, it's difficult to know what you've done in your Funcs.pm module that may be allowing you to import everything without using EXPORT and EXPORT_OK arrays. Perhaps you did not include the package Funcs; line in your module, as #JonathanLeffler suggested in the comments. Perhaps you did something else. Perl is one of those languages where people pride themselves in the TMTOWTDI mantra, often to a detrimental/counter-productive level, IMHO.
The 2nd example you presented is very different and fairly straightforward. When you have something like:
use WWW::Mechanize;
my $mech = new WWW::Mechanize;
$mech->get("http://www.google.com");
you're simply instantiating an object of type WWW::Mechanize and calling an instance method, called get, on it. There's no need to import an object's methods because the methods are part of the object itself. Modules looking to have an OOP approach are not meant to export anything. They're different situations.

Can I use MYSQL spatial extensions with sqlalchemy?

I am looking for a way to map spatial data to sqlalchemy objects. Does someone can tell me if there is such a way? Thanks!
You could create MySQL spatial columns with GeoAlchemy, but this package is no longer maintained. It's not possible to do it with GeoAlchemy2, as it does not support MySQL according to the documentation.
Anyway, GeoAlchemy is not necessary to use MySQL spatial columns in Python. You can achieve it by creating the custom Geometry class:
from sqlalchemy import func
from sqlalchemy.types import UserDefinedType
class Geometry(UserDefinedType):
def get_col_spec(self):
return 'GEOMETRY'
def bind_expression(self, bindvalue):
return func.ST_GeomFromText(bindvalue, type_=self)
def column_expression(self, col):
return func.ST_AsText(col, type_=self)
Then, you can use this custom type inside your model:
your_column = Column(Geometry, nullable=False)
Yes, you'll want to look at the GeoAlchemy package.
Brings a column type to the table called GeometryColumn.
Filtering is very sqlalchemic also. From the docs:
s = session.query(Spot).filter(Spot.geom.kml == '<Point><coordinates>-81.4,38.08</coordinates></Point>').first()
It's no further away than a simple pip install GeoAlchemy.

How to store web sessions in MySQL for CherryPy 3.2.2?

I found many examples for older versions of CherryPy but they each referenced importing modules not found in cherrypy 3.2.2. Looking in the documentation, I found a reference to the fact that there is built in functionality with storage_type (one of ‘ram’, ‘file’, ‘postgresql’).
For a start you could take a look at
https://github.com/3kwa/cherrys
how this guy writes his own session class and overwrites some methods. He does it for redis not MySQL. You would write methods for MySQL. A very similar class already exists in cherrypy in "cherrpy/lib/sessions.py":
class PostgresqlSession(Session)
which is very similar to what you want. I'd say, take the implementing approach from the "3kwa" but instead of his RedisSession-class copy the PostgresqlSession-class from "cherrpy/lib/sessions.py" and alter to match proper MySQL-Syntax.
A possible path could be:
Download the "cherrys.py" from above link and rename into "mysqlsession.py". Overwrite the "RedisSessions(Session)" with the "PostgresqlSession(Session)" from "cherrpy/lib/sessions.py" and rename to "MySQLSession(Session)". Be sure to add
locks = {}
def acquire_lock(self):
"""Acquire an exclusive lock on the currently-loaded session data."""
self.locked = True
self.locks.setdefault(self.id, threading.RLock()).acquire()
def release_lock(self):
"""Release the lock on the currently-loaded session data."""
self.locks[self.id].release()
self.locked = False
to your new "MySQLSession"-class (like it is done in RedisSession(Session). Alter the the PostgreSQL-Syntax to match MySQL-Syntax (that shouldn't be difficult). Put the "mysqlsession.py" somewhere below your project directory and import in the application with
import mysqlsession
and use
cherrypy.lib.sessions.MySQLSession = mysqlsession.MySQLSession
in the initialization of you app. In the config
tools.sessions.storage_type : 'mysql'
and the parameters (like host, port, etc.) like you would with class "PostgreSQL".
I can be wrong all along. But this is how I would try to solve this.

Is it bad to prefix all of my framework class names?

I develop a lot of frameworks for Flash games and applications. I have always prefixed my class names with a random character or two, to avoid conflict with class names that the developer may already have, for example:
class LEntity
Recently I had a co-worker blast me for poor and "annoying" naming of classes who then proceeded to rename every class in the frameworks I've created for people here to use.
I'm having trouble explaining my reasoning thoroughly enough for him to accept what I've done as a good approach.
Is what I've done above actually a bad thing? If not, how can I explain otherwise? If so, why?
Comments are asking about namespaces - I know AS3 in this example has what I know to be called a namespace but I'm not sure if this is the same thing or if it can be used as expected.
Given that Actionscript supports namespaces, there is no reason to use prefixes simply to prevent naming clashes. That's what namespaces are for.
Some people like to use namespaces to significy member variables (ie, underscore prefix, or sometimes m_) and that has some merit, but simply for the sake of name clashing no.
It sounds like you don't quite understand what namespacespackages are in AS3.
An example:
//Class1.as
package com.test.someModule { //This is the package/namespace
public class Class1 {...}
}
//Class2.as
package com.test.otherModule {
import com.test.someModule.Class1; //Class1 can be used as "Class1" now. Otherwise you would do "com.test.someModule.Class1"
import com.test.someModule.*; //You can also use the "*" to "import" all classes in that package
}
I have to agree with your co-worker, your class names are 'annoying'.
In Actionscript 3 we use the package name to define the namespace of a class. If you're not sure what namespace means, take the wikipedia definition (as of the time of writing):
"In general, a namespace is a container for a set of identifiers
(names), and allows the disambiguation of homonym identifiers residing
in different namespaces."
So you will never "conflict with class names" as long as you name your packages correctly. Most developers use what is called the reverse domain notation to name their packages (e.g com.mywebsite.MyGenericNamedClass). Domain names are unique so it's very unlikely you would clash with another class.
As a rule of thumb the class name should be as descriptive as possible, so some of your class names will be the same as someone else's class. Take the default Sprite class for instance:
import flash.display.Sprite;
import uk.co.mywebsite.Sprite;
if you then initialize an object:
var mySprite:Sprite = new Sprite();
The compiler would not know which Sprite you want to initialize (is it the flash sprite or your own custom sprite), and it would throw an error.
The solution is simple: because your packages have been named properly, all you need to do is to use the full class name including the package name to initialize your object:
var mySprite:uk.co.mywebsite.Sprite = new uk.co.mywebsite.Sprite();
var myOtherSprite:flash.display.Sprite = new flash.display.Sprite();
Mind you, you would rarely need to do that. This is only necessary if you want to use those two classes (the default Sprite and your own Sprite) in the same scope. Generally, you would only import your own class:
/* we are not importing this any more
import flash.display.Sprite;*/
//only importing my own class
import uk.co.mywebsite.Sprite;
/* now I can initialize my object without using the full class name, and the compiler knows
I mean my own Sprite class */
var mySprite:Sprite = new Sprite();