[sqlalchemy] Introspecting sequences

2015-02-05 Thread Catherine Devlin
I want* to get the current values of all the sequences in a database, or at
least the ones that are being used to autoincrement primary keys.

Can I find those with SQLAlchemy?  I haven't been able to find them in
metadata after ``metadata.reflect()`` yet, or with ``reflection.Inspector``.
 ``metadata._sequences`` is empty even though schemas definitely exist in
the database (and I shouldn't rely on an underscore-preceded attribute
anyway). The closest I've been able to find is::

str(meta.tables['mytable'].c.id.server_default.arg)
nextval('mytable_id_seq'::regclass)

... but trying to scrape my sequence names out of strings like that feels
dangerous.

* - Reason: For DDLGenerator, I want to be able to dump SQLAlchemy
statements that duplicate a small database in SQLAlchemy terms.  In this
case, for py.test fixtures - so you can work out your test database in live
SQL, or with a tool like rdbms_subsetter, and then generate a .py file that
fits nicely into your unit testing environment.  So far so good, except I'm
inserting rows with their primary key values, but nothing is updating the
values of the sequences associated with them, so the next attempted insert
fails with a primary key violation.

Thanks,
-- 
- Catherine
http://catherinedevlin.blogspot.com

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Generating models from data

2014-07-28 Thread Catherine Devlin
Hi, everybody,

Apologies for the self-promotion, but I just wrote up a way to
automatically generate SQLAlchemy models automatically based on the
(not-yet-relationalized) data, and I want to boast:

ddlgenerator --inserts sqlalchemy rawdata.yaml

(or .xml, .json, .html)

I crave your bug reports!

http://catherinedevlin.blogspot.com/2014/07/auto-generate-sqlalchemy-models.html
https://pypi.python.org/pypi/ddlgenerator/

Thanks,
-- 
- Catherine
http://catherinedevlin.blogspot.com

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] capture SQL without executing

2013-03-19 Thread Catherine Devlin
Hi!  I'm looking for a way to capture the text of SQL that SQLAlchemy is
prepared to execute, without actually executing the SQL.  There has to be a
way, right?

Why (#1): I'm working on a DDL-generating tool for DBAs who no-way-no-how
will let some Python tool change their database directly.

Why (#2): I can grab the SQL of most of the statements I want to run with
str() calls, like str(my_table.update().values(foo='bar')) and
str(sqlalchemy.schema.CreateTable(new_table)).  But this doesn't generate
the same SQL that actually executing does; specifically, it doesn't create
the PK as SERIAL in postgres.

My code:
import sqlalchemy

connection_string = 'postgresql://user:pw@localhost/db'
engine = sqlalchemy.create_engine(connection_string, echo=True)
metadata = sqlalchemy.MetaData(bind=engine)

new_table = sqlalchemy.Table('new_table', metadata,
 sqlalchemy.Column('id',
sqlalchemy.types.Integer,
   primary_key = True,
autoincrement = True))
print(sqlalchemy.schema.CreateTable(new_table))
print('\n\n-\n\n')
metadata.create_all(engine)

Result:

CREATE TABLE new_table (
id INTEGER NOT NULL,
PRIMARY KEY (id)
)

-

2013-03-19 21:12:45,248 INFO sqlalchemy.engine.base.Engine
CREATE TABLE new_table (
id SERIAL NOT NULL,
PRIMARY KEY (id)
)

As far as I can tell, Alembic isn't quite right for this task; I'm writing
for users who won't want to set up an alembic directory with named
revisions and so forth.  But something analogous to Alembic's offline
mode is exactly what I'm looking for for SQLAlchemy.

Thanks,
-- 
- Catherine
http://catherinedevlin.blogspot.com

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] reflected DATETIME

2011-01-18 Thread Catherine Devlin
I'm trying to build a MySQL-PostgreSQL migration tool that reflects tables
from MySQL, then creates them in pg.

So far so good, except that when SQLAlchemy reflects a MySQL table with a
DATETIME column, it reflects it as a sqlalchemy.types.DATETIME, then tries
to create a DATETIME in PostgreSQL.  I get

LINE 7:  SFDC_LAST_UPDATED DATETIME DEFAULT '-00-00 00:00:00' ...

sqlalchemy.exc.ProgrammingError: (ProgrammingError) type datetime does not
exist

I haven't been able to come up with a way around this... either change the
column's type after reflection to DateTime (how?), or command sqlalchemy to
reflect them as sqlalchemy.DateTime in the first place (how?), or... I don't
know.  I can't hard-code the column definitions b/c I want the tool to adapt
when the original (MySQL) database is changed.

Can anybody help?

Thanks very much!
-- 
- Catherine
http://catherinedevlin.blogspot.com

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] many-to-many doc clarification suggestion

2010-11-22 Thread Catherine Devlin
When I went looking for docs to remind myself how to build a many-to-many
relationship, the first doc I found at
http://www.sqlalchemy.org/docs/orm/extensions/declarative.html

keywords = Table(
'keywords', Base.metadata,
Column('author_id', Integer, ForeignKey('authors.id')),
Column('keyword_id', Integer, ForeignKey('keywords.id'))
)

class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True)
keywords = relationship(Keyword, secondary=keywords)

... confused me completely, because I couldn't tell whether ``keywords`` was
the association table?  (Which seemed to be implied by
``secondary=keywords``).  And ``keywords`` has a foreign key
(``keyword_id``) which points to ``keywords.id``, a column that... doesn't
exist?  Trying to run it threw ``sqlalchemy.exc.NoReferencedColumnError:
Could not create ForeignKey 'keywords.id' on table 'keywords': table
'keywords' has no column named 'id'``

Anyway, I suggest that it would be much less confusing to just refer to the
ORM tutorial example, Building a Many To Many Relationship at
http://www.sqlalchemy.org/docs/orm/tutorial.html, which I think is much more
clear but which unfortunately only shows up at position #14 in the search
results of a many-to-many search.

Thanks!

-- 
- Catherine
http://catherinedevlin.blogspot.com

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: interpret (string) NULLs as empty strings, not None

2009-08-21 Thread Catherine Devlin

On Thu, Aug 6, 2009 at 3:14 PM, Michael Bayermike...@zzzcomputing.com wrote:

 When populating objects through the ORM, I'd like to interpret all
 NULL values fetched from VARCHAR2 / NVARCHAR2 columns in the database
 as empty strings ('') instead of `None`s.

 use a TypeDecorator that creates that behavior.

Belated but huge thanks for this.  This is a much simpler solution
than I had hoped for.

class NullCatchingString(types.TypeDecorator):
# NULL results are returned as empty strings.
impl = types.String
def process_result_value(self, value, engine):
if value:
return value
else:
return ''

 To get a global effect,
 perhaps in your imports make sure that your custom type overrides the
 usage of String/Unicode in your Table definitions.

In this case, my tables are autoload=True, so I don't think overriding
String will help.  However, I realized that I've got a limited number
of columns that need this behavior, and explicitly defining those
columns isn't too much of a pain after all.

tbl = Table('mytable', metadata,
 Column('suchandsuch', NullCatchingString),
 autoload=True, autoload_with=engine)

Thanks again!
-- 
- Catherine
http://catherinedevlin.blogspot.com/
*** PyOhio * July 25-26, 2009 * pyohio.org ***

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] interpret (string) NULLs as empty strings, not None

2009-08-06 Thread Catherine Devlin

When populating objects through the ORM, I'd like to interpret all
NULL values fetched from VARCHAR2 / NVARCHAR2 columns in the database
as empty strings ('') instead of `None`s.

Is there any way to set that behavior globally?  Failing that, how
would you recommend doing it?

(I'm using Oracle, which does not distinguish between empty strings
and NULLs; but, once my data is on the Python side, I do a zillion
string operations on it and don't want to bother checking for `None`s
every time I slice, check `in`, etc.  When I send data back to Oracle,
any empty strings I send will be converted back to NULLs as Oracle
saves them, anyway.)

Thanks!
-- 
- Catherine
http://catherinedevlin.blogspot.com/
*** PyOhio * July 25-26, 2009 * pyohio.org ***

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: preview an update?

2009-06-23 Thread Catherine Devlin
On Thu, Jun 18, 2009 at 4:57 PM, Michael Bayermike...@zzzcomputing.com wrote:

 you can get most of this stuff from the session without any flush
 occurring.  at the object level are the new, dirty, and deleted
 collections on Session.   At the attribute level the
 attributes.get_history() method will illustrate the full changes made
 since the last flush on an individual object attribute.  get_history()
 should be in the API docs.

Thank you!  get_history is just what I needed.  However, I spent a
long time being confused by something that I think is a very obscure
bug.

If you make an update to a table that has a relation to a view, then
get_history on an attribute in the view, then the history is
forgotten.  I'm attaching a file that duplicates it completely, but
here's the gist of it (after setting up as described in the docs' ORM
tutorial):

 ed = session.query(User).first()
 print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
((), [u'Ed Jones'], ())
 ed.fullname = 'Eduardo Jones'
 print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
(['Eduardo Jones'], (), [u'Ed Jones'])
 # so far so good
 print sqlalchemy.orm.attributes.get_history(ed.userview, 'name')
((), [u'ed'], ())
 print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
((), ['Eduardo Jones'], ())

... now get_history thinks fullname has always been Eduardo Jones.

Is this a bug I should file, or something I should have expected?

Thanks as always!
-- 
- Catherine
http://catherinedevlin.blogspot.com/
*** PyOhio * July 25-26, 2009 * pyohio.org ***

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---

from sqlalchemy import create_engine
engine = create_engine('sqlite:///:memory:', echo=False)
from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
metadata = MetaData()
users_table = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(12)),
Column('fullname', String(40)),
Column('password', String(40))
)
metadata.create_all(engine) 

class User(object):
def __init__(self, name, fullname, password):
self.name = name
self.fullname = fullname
self.password = password

def __repr__(self):
   return User('%s','%s', '%s') % (self.name, self.fullname, self.password)

from sqlalchemy.orm import mapper, relation, backref
mapper(User, users_table) 

ed_user = User('ed', 'Ed Jones', 'edspassword')

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
session.add(ed_user)
session.commit()

#
# everything up to here comes from the ORM tutorial at http://www.sqlalchemy.org/docs/05/ormtutorial.html

engine.connect().execute('CREATE VIEW userview AS SELECT id, name FROM users')
class UserView(object):
pass
userview = Table('userview', metadata, 
 Column('id', ForeignKey('users.id'), primary_key=True), 
 autoload=True, autoload_with=engine)
mapper(UserView, userview,
   properties={'user': relation(User, uselist=False, lazy=True,
   backref=backref('userview', uselist=False))})   

import sqlalchemy.orm.attributes
ed = session.query(User).first()
print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
ed.fullname = 'Eduardo Jones'
print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
print sqlalchemy.orm.attributes.get_history(ed.userview, 'name')
print sqlalchemy.orm.attributes.get_history(ed, 'fullname')


[sqlalchemy] preview an update?

2009-06-18 Thread Catherine Devlin

I'm building a complex ETL tool with SQLAlchemy that will sometimes
need to let the user preview a changed record - not actually carry
out the update, just find out which fields would be changed, and to
what values.  I'm having trouble figuring out a good way to do it.

Is there a way to get a sort of preview of an update - get information
about what updates are pending for the next flush, or get a flush to
report back its changes without actually performing it?

One approach would be to set echo to True, let the user see the echo,
then roll back the transaction, but there are a couple reasons I don't
think that will work for me.  I don't want to make the user mentally
parse SQL statements; I'd like to get a dict of the pending changes
and write my own code to display them attractively, instead.  Anyway,
I'm having trouble getting echo to work on this app.  (The whole thing
is part of a TurboGears project, and my echoes aren't showing up,
probably because of something I don't understand about the SQLAlchemy
logging configuration.)

Just getting to the bind variables that will ultimately be sent along
with the UPDATE statement would be a great solution, and I'm trying to
figure out where I could get them.  Right now, it looks like the
`params` dict is assembled in Mapper._save_obj in orm/mapper.py, used
at line 1376 to issue connection.execute, then discarded.  I'm
considering overriding Mapper with my own version whose __save_obj can
exit at this point, returning `params`, if it is invoked with a
preview=True parameter... but that seems a little scary.  __save_obj
is a long method, and I'd have to keep my app's version of it
carefully synched with the canonical sqlalchemy version indefinitely.

Thanks in advance for reading through, and for any any suggestions!
-- 
- Catherine
http://catherinedevlin.blogspot.com/
*** PyOhio * July 25-26, 2009 * pyohio.org ***

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---