PyCharm SQLAlchemy autocomplete - python

I started evaluating PyCharm 3 professional edition because I will be working on several Pyramid + SQLAlchemy projects.
One of the things I would really love to have is SQLAlchemy autocomplete.
I created a new starter project with the alchemy scaffold following these instructions. I also installed the SQLAlchemy package for the interpreter and virtual environment I am using for this project.
Also, when I created a new pycharm project for this code, the IDE suggested me to install the pyramid, sqlalchemy and other packages. Of course I accepted the suggestion and let the IDE install all of those packages.
In the models.py file, the DBSession is declared as follows:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
In the views.py file, the DBSession is used this way:
one = DBSession.query(MyModel).filter(MyModel.name == 'one').first()
So I started playing with the IDE and did something like this: typed DBSession. and the IDE just gave me some few suggestions, within which the 'query' function was not listed. Then I tried typing: DBSession.query(MyModel). and pressed Ctrl+Space to try to get suggestions and a 'No suggestions' message showed up.
I would really like to have the SQLAlchemy suggestions of functions that I could use on my DBSession variable (like filter, filter_by, first, etc). I would say that this is mandatory for me :)
Is there something I am missing? Or, PyCharm doesn't support this?

The solution I've found to this (picked up from somewhere on the web) was to type hint the DBSession instance like this:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
""":type: sqlalchemy.orm.Session"""
After this the code completion seems to work fine everywhere in the project

Note that the tutorial states:
This guide was written for PyCharm 2.7.3, although many of the topics apply for PyCharm 3.
In PyCharm 3 Professional, it is much easier to install Pyramid and start using a scaffold. See one of my video tutorials Pyramid in PyCharm in 5 minutes at 1:17 specifically.
Also you might want to blow away your project and start fresh if stuff doesn't work as expected.
PyCharm 3 Professional supports SQAlchemy as follows.
Code insight (2.6+)
Possibility to view database structure in a diagram. Refer to the section Working with Diagrams.
Code completion and resolve. (3.0+)
See more information on how to use code completion.

I use a type declaration after a variable assignment:
from sqlalchemy import create_engine
from sqlalchemy.engine import Engine
...
engine = create_engine(connect_str, max_overflow=10)
engine: Engine
As a use for variables in for loop, I used:
for table, meta in tables.items():
meta: Table
pass
in which, tables is sqlalchemy.orm.mapper.Mapper, and table is an imported type:
from sqlalchemy import create_engine, Table

If anyone gets here now, the best solution I'v seen for this issue can be found here. To save you the click:
from contextlib import contextmanager
from typing import ContextManager
#contextmanager
def session() -> ContextManager[Session]:
yield Session(...)

Related

Cassandra warning about CQLENG_ALLOW_SCHEMA_MANAGEMENT

When I run my Python scripts that use Cassandra, I get the following warning:
/home/ubuntu/.local/lib/python2.7/site-packages/cassandra/cqlengine/management.py:545: UserWarning: CQLENG_ALLOW_SCHEMA_MANAGEMENT environment variable is not set. Future versions of this package will require this variable to enable management functions.
Sounds reasonable enough, but I searched and I searched and couldn't figure out what CQLENG_ALLOW_SCHEMA_MANAGEMENT is or how to set it.
What is it and what should I set it to?
Looking at the code of the driver, it seems that it is a boolean flag that will indicate if the application will be allowed or not to modify the schema with the application.
There are several examples like this fix for a django project or this eventsourcing code that solves the issue with a quick and dirty approach, setting explicitly the value with something like:
if os.getenv('CQLENG_ALLOW_SCHEMA_MANAGEMENT') is None:
os.environ['CQLENG_ALLOW_SCHEMA_MANAGEMENT'] = '1'
Doing some additional research, Srikanth Bemineni's post in the driver forum, mentioned that he was able to solve the issue using the new integrated cqlengine in the cassandra python driver instead of using the cqlengine from the module, but I couldn't figure out what was he referring to.

viewing tables with pyramid seed

I'm using this seed https://github.com/Pylons/pyramid_blogr
The seed uses sqlite, sqlalchemy and the pyramid frame work.
I have not modified the seed at all.
How do I print out my tables, from a shells?
Thank you for the help.
I am new to pyramid, and python, but I have done introduction work on node.js and django.
I used the sqlite3 command line with, 'sqlite3 gw.db' (gw is my app named), but i think this started a new db instance.
I am working on an Ubuntu 14.04 server with a mean stack installed.
To print sqlite tables via shell, use the sqlite3 command-line utility. It's not clear whether you want to print a list of tables, the database schema, or in what output format, but all of that is covered in the documentation.

Enums in SQLite

My model uses a couple of Enum's for various columns, creating the tables using SQLAlchemy's create_all() method works fine in PostgreSQL, but it doesn't work with SQLite, it just stalls.
The problem seems to be with creating Enum's, as far as I can tell sqlite doesn't support these, but according to SQLAlchemy's docs that shouldn't pose a problem. When I try to create_all() on an sqlite memory db it just stalls, even with echo=True no output appears.
I tried the following code to demonstrate the problem:
from sqlalchemy import create_engine, Enum
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
e = Enum('foo', 'bar', metadata=Base.metadata)
engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(bind=engine)
When I run this script it shows no output whatsoever, it just stalls. Python uses 100% CPU and the script never ends, until I ctrl-c it.
When I try to create_all() on my actual schema it does echo some PRAGMA commands trying to determine if tables exist, but then it stalls on the creating the Enums. I tried to remove code from the model definition until it worked just fine, this was when I figured out it's the Enums.
I tried to run this on Python 3.4 with SQLAlchemy 0.9.6 using SQLite 3.7.13.
A friend ran into exactly this same problem recently, and it looks to me like an infinite-loop bug in SQLA (which I should really report, so thanks for this minimal testcase :)).
Just remove the metadata= kwarg from your real code; as long as the enum is used as a type inside a declarative class, it'll inherit the right metadata anyway.

Pattern to get rid of imports in modules as in web2py controllers

I am new to web2py and python both. I am writing a sample blog app in this framework. I want to split the business logic that gets called in each controller method to it's own module, and found this example helpful:
http://www.web2pyslices.com/slice/show/1478/using-modules-in-web2py
Cleaning up web2py my controllers
As you can see, you need to import objects in modules or set them through globals.current. The controller can refer to "db" and "request" instances (for example) without any import. What kind of coding mechanism makes it possible in controller but not elesewhere?
The web2py framework does a lot of behind the scenes work to make all that stuff available.
For example, when you go to a URL like host/app/controller, that controller is called by web2py (starting with something in web2py.py) that handles importing web2py modules, providing request/response objects, etc.
Things placed in modules, however, are intended to be standalone Python code, not necessarily specific to web2py.
Found the answer:
Looks like how web2py works is by compiling the python code for the controllers and models and views on the fly. It runs them in it's special 'environment'
Related snippets of code are:
https://github.com/web2py/web2py/blob/master/gluon/main.py#L205-263
In the file above, look at: build_environment, run_models_in, run_controller_in functions (below):
https://github.com/web2py/web2py/blob/master/gluon/compileapp.py#L385-487
https://github.com/web2py/web2py/blob/master/gluon/compileapp.py#L504-539
https://github.com/web2py/web2py/blob/master/gluon/compileapp.py#L542-607
Which run the python code in a 'restricted' environment:
https://github.com/web2py/web2py/blob/master/gluon/restricted.py#L197-225

How do I dynamically import a module in App Engine?

I'm trying to dynamically load a class from a specific module (called 'commands') and the code runs totally cool on my local setup running from a local Django server. This bombs out though when I deploy to Google App Engine. I've tried adding the commands module's parent module to the import as well with no avail (on either setup in that case). Here's the code:
mod = __import__('commands.%s' % command, globals(), locals(), [command])
return getattr(mod, command)
App Engine just throws an ImportError whenever it hits this.
And the clarify, it doesn't bomb out on the commands module. If I have a command like 'commands.cat' it can't find 'cat'.
I was getting import errors when importing this way when my folder/package was named "commands". I renamed the package to "cmds" and everything worked. I'm guessing there was a conflict with a builtin named "commands". Also, I don't know if it matters, but I only passed a value for the name parameter when calling import:
__import__('cmds.' + command_name)
Nick Johnson from the AppEngine team wrote up a blog post on this topic that may help you:
Webapps on App Engine, part 6: Lazy loading
The whole batch of them are recommended reading.
My AppEngine framework MVCEngine dynamically imports controller classes. The actual code in-context can be browsed on Google Code.
Briefly, here's how I do it:
controller_name = "foo"
controller_path = "app/controllers/%s_controller.py" % controller_name
controller = __import__(controller_path)
controllerClass = classForName(controller_name, namespace=controller.__dict__)
and the classForName function:
def classForName(name, *args, **kw):
ns = kw.get('namespace',globals())
return ns[name](*args)
I haven't read Nick's article on Lazy Loading, referenced above, but he is pretty much the authority on things AppEngine, and he has a better understanding than I do of the (all-important) performance characteristics of different approaches to coding for AppEngine. Definitely read his article.
You may want to have a look on mapreduce.util.for_name which lets you to dynamically import class/function/method. I promise :) I will wrap that in a blogpost.

Categories

Resources