Re: [sqlalchemy] Issue with "complex" many 2 many delete, FK violation

2021-04-14 Thread Mark Aquino
It's still a little bit long because you need the many to many
relationships off chain to at least variable_region, but I can send that if
the below doesn't clear things up for you:

I finally got it to work by updating the "business logic" script that (at
least from my current analysis and testing) but in order to do so the
chain.variable_regions and chain.constant_regions collections/relationships
must be manually emptied (along with a couple other minor tweaks and some
errors i spotted in the original example but that don't have an impact on
the problem)  The question/"issue" I have is that I was expecting those
associations to be removed automatically if I delete the chain object.  Is
that incorrect?


molecules = (
session.query(TestMolecule)
.filter(TestMolecule.label.in_(["molecule1", "molecule2", "molecule3"]))
.all()
)
for molecule in molecules:
session.delete(molecule)
orphan_chains = (
session.query(TestChain).filter(~TestChain.molecules.any()).all()
)
for orphan_chain in orphan_chains:
orphan_chain.var_regions.clear()
orphan_chain.const_regions.clear()
session.delete(orphan_chain).



On Wed, Apr 14, 2021 at 1:19 PM Mike Bayer  wrote:

>
>
> On Wed, Apr 14, 2021, at 11:45 AM, Mark Aquino wrote:
>
> Thanks. I’ll take a stab at this approach. To back up a little bit my main
> confusion is around why the association tables aren’t updating as expected.
> As I understand it, without cascades configured, the default behavior
> should be to remove associations from those tables.
>
>
> that's correct, assuming the objects on either side are being deleted or
> if the collection to which the association refers towards is being
> emptied.
>
>
>
>
>
> If I configure cascades like on delete=cascade then the associated objects
> themselves are set to also be deleted (as I would expect). In the no
> cascades scenario, if I delete the test_chain then the orm should remove
> its rows from test_chain_var_region and test_chain_const_region (this
> occurs after the test_molecule is already deleted so any corresponding
> test_molecule_chain rows are already removed) but the constraint error
> occurs because it leaves them there.
>
>
> Here is where we need to work with a more succinct example, as the example
> given is too long and verbose so it's hard for me to isolate
> where SQLAlchemy doing the wrong thing, as in the case earlier where it
> seemed to me the scope of the related delete statement needed to be
> expanded, but that wasn't what you were tring to do.
>
> Below is a structure that paraphrases what I think is part of your model,
> more or less, which at the moment is able to delete the "Chain" object.  If
> you can modify the below script to illustrate more specifically the
> structural pattern that's present and the originating, single delete()
> statement you expect to succeed, then I can give you a better answer what's
> going on.
>
> from sqlalchemy import Column
> from sqlalchemy import create_engine
> from sqlalchemy import ForeignKey
> from sqlalchemy import Integer
> from sqlalchemy import Table
> from sqlalchemy.ext.declarative import declarative_base
> from sqlalchemy.orm import relationship
> from sqlalchemy.orm import Session
>
> Base = declarative_base()
>
>
> class Molecule(Base):
> __tablename__ = "molecule"
>
> id = Column(Integer, primary_key=True)
>
> chain = relationship("Chain", back_populates="molecules")
> chain_id = Column(ForeignKey("chain.id", ondelete="CASCADE"))
>
>
> chain_to_related = Table(
> "chain_to_related",
> Base.metadata,
> Column("chain_id", ForeignKey("chain.id"), primary_key=True),
> Column("related_id", ForeignKey("related_to_chain.id"),
> primary_key=True),
> )
>
>
> class Chain(Base):
> __tablename__ = "chain"
> id = Column(Integer, primary_key=True)
> related = relationship("RelatedToChain", secondary=chain_to_related)
>
> molecules = relationship("Molecule", back_populates="chain")
>
>
> class RelatedToChain(Base):
> __tablename__ = "related_to_chain"
> id = Column(Integer, primary_key=True)
>
>
> e = create_engine("postgresql://scott:tiger@localhost/test", echo=True)
> Base.metadata.drop_all(e)
> Base.metadata.create_all(e)
>
> s = Session(e)
>
> c1 = Chain()
> m1 = Molecule(chain=c1)
> r1 = RelatedToChain()
> c1.related.append(r1)
>
> s.add_all([c1, m1, r1])
> s.commit()
>
>
> s.delete(c1)
> s.commit()
>
>
>
>
>
>
>
>
>
>
>

Re: [sqlalchemy] Issue with "complex" many 2 many delete, FK violation

2021-04-14 Thread Mark Aquino
Thanks. I'll take a stab at this approach. To back up a little bit my main 
confusion is around why the association tables aren't updating as expected. As 
I understand it, without cascades configured, the default behavior should be to 
remove associations from those tables. If I configure cascades like on 
delete=cascade then the associated objects themselves are set to also be 
deleted (as I would expect). In the no cascades scenario, if I delete the 
test_chain then the orm should remove its rows from test_chain_var_region and 
test_chain_const_region (this occurs after the test_molecule is already deleted 
so any corresponding test_molecule_chain rows are already removed) but the 
constraint error occurs because it leaves them there. It works as expected with 
deleting the molecule, and test_molecule_chain rows are removed but not 
test_chains hence why I need to perform the additional logic to remove the 
stranded chains that are left behind but not linked to any test_molecules 
anymore. Am I doing something differently in my test_molecule configuration 
that I'm just not seeing?

Mark Aquino

From: sqlalchemy@googlegroups.com  on behalf of 
Mike Bayer 
Sent: Wednesday, April 14, 2021 11:21:28 AM
To: noreply-spamdigest via sqlalchemy 
Subject: Re: [sqlalchemy] Issue with "complex" many 2 many delete, FK violation


hey there-

The general strategy, if you want to write business logic that checks things, 
takes other actions, etc. when changes occur in the session, is to use the 
before_flush event handler:  
https://docs.sqlalchemy.org/en/14/orm/events.html?highlight=before_flush#sqlalchemy.orm.SessionEvents.before_flush

in this event, you can review the linkages on the objects in question and emit 
additional statements if desired.  Note this is because you said you didn't 
want to use CASCADE rules on your foreign keys; that would allow your script to 
pass without change.

The general form of using before_flush(), where I've paraphrased a few of your 
business rules below in the form of pseduocode, looks like:

from sqlalchemy import event


@event.listens_for(SomeSessionOrFactory, 'before_flush')
def receive_before_flush(session, flush_context, instances):
for obj in session.deleted:
if isinstance(obj, TestMolecule):
check_obj_not_linked_to_other_test_molecules(obj)
elif isinstance(obj, TestChain):
if should_delete_related_test_mol_sequence(obj):
session.delete(obj.related_test_mol_sequence)

# ... etc


Obviously you'd need to work out the specifics of your model here, but within 
before_flush() you can respond to all objects that have pending changes and/or 
deletions, and add additional custom rules and actions where you are free to 
further modify the state of the Session, which will take effect within this 
same flush operation.






On Tue, Apr 13, 2021, at 5:29 PM, Mark Aquino wrote:
Hi Mike,

Sorry about the indentations.

I'm not sure I understand the changes you made to the script after delete as it 
removes all test_chains, test_var_regions, and test_const regions that are 
still referenced by the other test_molecules.   The only way I've been able to 
get the delete to work properly is to manually delete test_var_regions and 
test_const_regions first and then delete the test_molecules, but the ideal 
outcome I'm trying to achieve is that when a test_molecule is deleted:

  1.   that the system checks if the chains connected to it are removed if they 
are not linked to other test_molecules.
  2.  if a test_chain is going to be deleted then
 *   the test_mol_sequence associated with it is deleted if it is no longer 
associated with any other test_chains
 *   any test_var_regions and test_const_regions are deleted if they are 
not associated with any other test_chains
  3.  and finally if a test_mol_sequence is deleted that any 
test_mol_sequence_features are deleted if they are not associated with any 
other test_mol_sequences.

To make things a little easier to explain, if we just are dealing with 
molecule1 and molecule4 there are only 3 unique test_chains: heavy_chain_1, 
light_chain_1, and heavy_chain_2
if I deleted molecule1, I would want to retain heavy_chain_2 and light_chain_1 
and delete heavy_chain_1 as it was no longer associated with any test_molecule. 
Ideally, then I would remove any test_const_regions and test_var_regions that 
are no longer associated with any test_chains.
Because heavy_chain_1 shares the same test_var_region as heavy_chain_2, that 
test_var_region would remain in the system but the test_const_region unique to 
heavy_chain_1 would be deleted along with the test_mol_sequence and 
test_mol_sequence_features associated with it.


molecule1.chains.add(heavy_chain_1)
molecule1.chains.add(light_chain_1)
#molecule2.chains.add(heavy_chain_2)
#molecule2.chains.add(light_chain_2)
#molecule3.chains.add(heavy_chain_1)

Re: [sqlalchemy] Issue with "complex" many 2 many delete, FK violation

2021-04-13 Thread Mark Aquino
Hi Mike,

Sorry about the indentations.

I'm not sure I understand the changes you made to the script after delete
as it removes all test_chains, test_var_regions, and test_const regions
that are still referenced by the other test_molecules.   The only way I've
been able to get the delete to work properly is to manually delete
test_var_regions and test_const_regions first and then delete the
test_molecules, but the ideal outcome I'm trying to achieve is that when a
test_molecule is deleted:

   1.  that the system checks if the chains connected to it are removed if
   they are not linked to other test_molecules.
   2. if a test_chain is going to be deleted then
  1. the test_mol_sequence associated with it is deleted if it is no
  longer associated with any other test_chains
  2. any test_var_regions and test_const_regions are deleted if they
  are not associated with any other test_chains
   3. and finally if a test_mol_sequence is deleted that any
   test_mol_sequence_features are deleted if they are not associated with any
   other test_mol_sequences.


To make things a little easier to explain, if we just are dealing with
molecule1 and molecule4 there are only 3 unique test_chains: heavy_chain_1,
light_chain_1, and heavy_chain_2
if I deleted molecule1, I would want to retain heavy_chain_2 and
light_chain_1 and delete heavy_chain_1 as it was no longer associated with
any test_molecule. Ideally, then I would remove any test_const_regions and
test_var_regions that are no longer associated with any test_chains.
Because heavy_chain_1 shares the same test_var_region as heavy_chain_2,
that test_var_region would remain in the system but the test_const_region
unique to heavy_chain_1 would be deleted along with the test_mol_sequence
and test_mol_sequence_features associated with it.

molecule1.chains.add(heavy_chain_1)
molecule1.chains.add(light_chain_1)
#molecule2.chains.add(heavy_chain_2)
#molecule2.chains.add(light_chain_2)
#molecule3.chains.add(heavy_chain_1)
#molecule3.chains.add(light_chain_2)
molecule4.chains.add(heavy_chain_2)
molecule4.chains.add(light_chain_1)


light_chain_1_sequence = TestMolSequence(content="taglconst1VAR1")
heavy_chain_1_sequence = TestMolSequence(content="tagheavyconstant1VAR2")
heavy_chain_2_sequence = TestMolSequence(content="tagheavyconstant2VAR2")
light_chain_2_sequence = TestMolSequence(content="taglconst1VAR3")


Does that make sense?



On Tue, Apr 13, 2021 at 4:50 PM Mike Bayer  wrote:

> Hi there -
>
> I would ask that you try to make sure your formatting is maintained when
> posting examples especially such long ones as I had to re-indent it in
> order to run this.
>
> The delete at the end is failing because of incomplete cascade rules.
> The DELETE against "test_mol_sequence" seeks to CASCADE as configured to
> the other three tables,, which then fail because there are non-cascading
> FKs in the association tables.   We can see this via the message:
>
> update or delete on table "test_var_region" violates foreign key
> constraint "test_chain_var_region_var_region_id_fkey" on table
> "test_chain_var_region"
> DETAIL:  Key (id)=(1) is still referenced from table
> "test_chain_var_region".
>
> [SQL: DELETE FROM test_mol_sequence WHERE test_mol_sequence.id = %(id)s]
>
>
> it's DELETEing from test_mol_sequence but the error is against a totally
> different table.  That's postgresql's cascade.
>
> if you want these CASCADEs to remain in place then you'd need to ensure
> that those linked rows can be deleted without any rows being present in the
> association tables.
>
> I can modify your test at the end to fully DELETE these rows without
> qualifying for those that have empty collections only and the script then
> passes, because now it's deleting those rows that would otherwise be
> dependent on by "test_var_region" and therefore "test_mol_sequence",  so
> there's nothing unexpected going on.Easiest solution here would be to
> add CASCADE rules to the association tables also.  If you want that to be
> prevented as you mention, and instead expect the script to explicitly
> delete those depending rows, then your script is already achieving that.
> the "business logic" so to speak in this case would be as below:
>
> orphan_chains = (
> session.query(TestChain).
> #filter(~TestChain.molecules.any()).
> all()
> )
> for chain in orphan_chains:
> session.delete(chain)
>
> orphan_vrs = (
> session.query(TestVarRegion)
> #.filter(~TestVarRegion.chains.any())
> .all()
> )
> for orphan_vr in orphan_vrs:
> session.delete(orphan_vr)
> orphan_crs = (
> session.query(TestConstRegion)
> #   .filter(~TestConstRegion.chains.any())
> .all()
> )
> for orphan_cr in orphan_crs:
> session.delete(orphan_cr)
> orphan_sequences = (

Re: [sqlalchemy] Issue with "complex" many 2 many delete, FK violation

2021-04-13 Thread Mark Aquino
I just wanted to clarify, the desire would be for the "test_var_region" and
"test_const_region" entities that are linked to other entities to remain
untouched and only to have their associations removed from the deleted
items. The output from the ORM indicates that the system is actually
attempting to delete them in some sort of cascade event a.) although that
is unspecified in any cascade option and b.) that is undesired in the first
place.

On Tue, Apr 13, 2021 at 10:04 AM maqui...@gmail.com 
wrote:

> I need to delete the association table rows for many to many relationships
> when I delete one, but the default behavior (to remove those rows) does not
> seem to work in my case.
>
> I have multiple levels of many to many relationships, as you can see in
> the example I'll provide below and when I delete a "parent" afterwards I
> try to clean up any children left behind that have no other parents.
> However, these children are in many to many relationships with other
> children and that's when the ORM fails to attempt to remove those children
> from their related association tables (at least, in a way that I expect).
>
> The issue is error is:
> def do_executemany(self, cursor, statement, parameters, context=None):
> if self.executemany_mode is EXECUTEMANY_DEFAULT:
> >   cursor.executemany(statement, parameters)
> E   sqlalchemy.exc.IntegrityError:
> (psycopg2.errors.ForeignKeyViolation) update or delete on table
> "test_var_region" violates foreign key constraint
> "test_chain_var_region_var_region_id_fkey" on table "test_chain_var_region"
> E   DETAIL:  Key (id)=(1) is still referenced from table
> "test_chain_var_region".
> E
> E   [SQL: DELETE FROM test_mol_sequence WHERE test_mol_sequence.id
> = %(id)s]
> E   [parameters: ({'id': 5}, {'id': 6}, {'id': 7}, {'id': 8},
> {'id': 9}, {'id': 10})]
> E   (Background on this error at: http://sqlalche.me/e/gkpj)
>
> The desired effect, of course, is that the rows in test_chain_var_region
> that reference the deleted chains removed.  I've tried several strategies
> to do this but with no change in this behavior.
>
> Cascades could be an issue, and I would rather handle removal of any
> "orphan" rows in the model tables via business logic than have the database
> cascade deletes and potentially remove rows that are associated with other
> objects.
>
> import pytest
> from sqlalchemy import (
> Table,
> Column,
> Integer,
> String,
> ForeignKey,
> create_engine,
> )
> from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
> from sqlalchemy.orm import relationship, Session
> from sqlalchemy.util import OrderedSet
>
>
> Base: DeclarativeMeta = declarative_base()
> engine = create_engine(
> "postgresql://postgres:postgres@localhost:5432/espresso", echo=True
> )
> test_chain_const_region = Table(
> "test_chain_const_region",
> Base.metadata,
> Column("chain_id", Integer, ForeignKey("test_chain.id")),
> Column("const_region_id", Integer, ForeignKey("test_const_region.id")),
> )
> test_chain_var_region = Table(
> "test_chain_var_region",
> Base.metadata,
> Column("chain_id", Integer, ForeignKey("test_chain.id")),
> Column("var_region_id", Integer, ForeignKey("test_var_region.id")),
> )
> test_molecule_chain = Table(
> "test_molecule_chain",
> Base.metadata,
> Column("molecule_id", Integer, ForeignKey("test_molecule.id")),
> Column("chain_id", Integer, ForeignKey("test_chain.id")),
> )
>
> test_mol_sequence_feat_mol_sequence = Table(
> "test_mol_sequence_feat_mol_sequence",
> Base.metadata,
> Column("mol_sequence_feat_id", Integer, ForeignKey("
> test_mol_sequence_feat.id")),
> Column("mol_sequence_id", Integer, ForeignKey("test_mol_sequence.id")),
> )
>
>
> class TestMolecule(Base):
> __tablename__ = "test_molecule"
> id = Column(Integer, primary_key=True)
> label = Column(String)
> chains = relationship(
> "TestChain",
> secondary=test_molecule_chain,
> collection_class=OrderedSet,
> back_populates="molecules",
> )
>
>
> class TestMolSequence(Base):
> __tablename__ = "test_mol_sequence"
>
> id = Column(Integer, primary_key=True)
> content = Column(String, nullable=False, unique=True)
> parent_features = relationship(
> "TestMolSequenceFeat",
> secondary=test_mol_sequence_feat_mol_sequence,
> collection_class=OrderedSet,
> back_populates="feature_sequences",
> single_parent=True,
> )
> chains = relationship(
> "TestChain", back_populates="mol_sequence", collection_class=OrderedSet
> )
>
>
> class TestMolSequenceFeat(Base):
> __tablename__ = "test_mol_sequence_feat"
>
> id = Column(Integer, primary_key=True)
> molecule_sequence_id = Column(
> Integer, ForeignKey("test_mol_sequence.id", ondelete="CASCADE"),
> )
> molecule_sequence = relationship("TestMolSequence",)
> start = Column(Integer)
> stop = Column(Integer)
> feature_sequences = relationship(
> "TestMolSequence",
> secondary=test_mol_sequence_feat_mol_sequence,
> collection_class=OrderedSet,
> back_populates="parent_features",
> # 

Re: [sqlalchemy] can you insert data for a model with a many to many relationship using alembic?

2021-03-10 Thread Mark Aquino
Thanks. I ended up using the models in the alembic file instead of bulk insert 
mappings. Your point is well taken about the caveats of the model being out of 
date but in this use case (just seeding the database) there’s no risk.

Mark Aquino

From: sqlalchemy@googlegroups.com  on behalf of 
Mike Bayer 
Sent: Tuesday, March 9, 2021 11:24:48 AM
To: noreply-spamdigest via sqlalchemy 
Subject: Re: [sqlalchemy] can you insert data for a model with a many to many 
relationship using alembic?


bulk_insert_mappings doesn't handle relationships in any case, if you wanted 
relationships to be persisted without doing the INSERT yourself you would need 
to use regular ORM Session unit of work patterns.

In Alembic, you would need to use ORM mappings inside of your alembic scripts, 
which is perfectly acceptable, the only issue with that is that if you import 
these models from your application, they might not match the state of the 
database for when the migration is running.so it might be better to create 
an ad-hoc mapping in your migration file.   Depending on how you are getting 
those Table objects, you can assign them to a new declarative model using 
__table__ (See 
https://docs.sqlalchemy.org/en/14/orm/declarative_tables.html#orm-imperative-table-configuration
 )   and you can make a new Session for the local transaction using 
Session(op.get_bind()).

if you wanted bulk_insert_mappings to apply directly to your manytomany table 
then you can map a class to that table and use the method, but I dont see much 
advantage to this vs. using plain table.insert(), in both cases it's a command 
with a list of dictionaries.


if you are looking to use session.flush(), that implies you should just use 
traditional unit of work patterns and you wouldn't be using 
bulk_insert_mappings, which is a special case method that IMO is not actually 
very useful compared to other APIs that already exist.


On Tue, Mar 9, 2021, at 9:58 AM, maqui...@gmail.com<mailto:maqui...@gmail.com> 
wrote:
I'm trying to create an alembic bulk insert statement to add a row into a model 
that has a relationship (many-to-many) with another table but don't know if 
this is possible or if so what syntax to use.

In my current alembic file I do this in two or more steps:
1.) I add the rows to the table represented by the model
2.) I add the rows to the mixer table for the model and its related model/table

like so:
g.session.bulk_insert_mappings(
CvConfiguration,
[
{
"controlled_vocabulary_type_id": controlled_vocabulary_type(
"cv_vessel_type"
),
"default_cv_id": cv_vessel_type("well_plate"),
},
],
return_defaults=True,
)

g.session.flush()

mix_cv_organization_cv_configuration_stmt = 
mix_cv_organization_cv_configuration.insert().values(
[
{
"cv_organization_id": cv_organization("biologics_generation_group"),
"cv_configuration_id": cv_configuration("cv_vessel_type", 
"well_plate"),
},
],
)
g.session.execute(mix_cv_organization_cv_configuration_stmt)

I'd really like to combine the relationship into the bulk_insert_mapping if 
possible, so if the relationship on the SqlAlchemy model is called 
"used_by_cv_organizations" my insert looks something like this, with the 
foreign key objects in a list or something.

g.session.bulk_insert_mappings(
CvConfiguration,
[
{
"controlled_vocabulary_type_id": controlled_vocabulary_type(
"cv_vessel_type"
),
"default_cv_id": cv_vessel_type("well_plate"),
"used_by_cv_organizations": [
cv_organization("biologics_generation_group")
],
},
],
return_defaults=True,
)

g.session.flush()

Is this possible? Does anyone know how to do it?




--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example. See http://stackoverflow.com/help/mcve for a full description.
---
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<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/f7ddef2f-9152-4b5a-a60e-bf51794f531bn%40googlegroups.com<https://groups.google.com/d/msgid/sqlalchemy/f7ddef2f-9152-4b5a-a60e-bf51794f531bn%40googlegroups.com?utm_medium=email_source=footer>.


--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code,

Re: [sqlalchemy] Re: Can't delete cascade many-to-many with polymorphic relationships unless using lazy=dynamic

2020-12-18 Thread Mark Aquino
Thanks. That could work. The reason we need specific relationships to the child 
class types is for our front end when it queries the data, which we use 
sqlalchemy-graphene to do, if we query the base class relationship it returns 
empty rows and makes pagination impossible as the front end is unable to know 
how many rows containing the desired type are present when the mixer table 
contains references to several different classes by using the id shared on the 
base class.

Mark Aquino

From: sqlalchemy@googlegroups.com  on behalf of 
Mike Bayer 
Sent: Thursday, December 17, 2020 9:32:40 PM
To: noreply-spamdigest via sqlalchemy 
Subject: Re: [sqlalchemy] Re: Can't delete cascade many-to-many with 
polymorphic relationships unless using lazy=dynamic

perhaps you are looking to set viewonly=True on this second relationship?  that 
will exclude it from any kind of persistence operation.it will only be used 
to load things in from the database but not accept or honor any mutations of 
data.

not sure why you need to have two relationships that are identical, but if you 
do, then yes you want only one of them to be the one that writes changes to the 
DB.

On Thu, Dec 17, 2020, at 7:40 PM, maqui...@gmail.com<mailto:maqui...@gmail.com> 
wrote:
My operating assumption is that sqlalchemy looks at each relationship and tries 
to delete it, but since the previous relationship to the same base class was 
already deleted, it throws the exception and the session rolls back.

The error from above is essentially the same as the actual error in my code 
base.  I guess ideally there would be a way to just disable that functionality 
but my solution works.  Just will take several hours to change everything 
correctly like this because we have about 200 models that are all 
interconnected like this. I apologize for not giving a proper working example I 
would have needed to create a brand new project unfortunately because the code 
base is so complicated
On Thursday, December 17, 2020 at 7:32:43 PM UTC-5 maqui...@gmail.com wrote:
1. target database = postgres,

example queries and stacktrace:

>>> from webapp.database.orm.models import ParentClass, ChildClass, 
>>> ChildChildClass
>>> p = ParentClass()
>>> c = ChildClass()
>>> cc = ChildChildClass()
>>> c.children.append(cc)
>>> p.children.append(c)
>>> session.add(p)
>>> session.commit()
>>> p = session.query(ParentClass).one()
>>> [cc for c in p.children for cc in c.children]
[ChildChildClass(id=UUID('1253a435-3330-4e36-bafc-ad8ff5176c4d'))]
>>> session.delete(p)
>>> session.flush()
Traceback (most recent call last):
  File "", line 1, in 
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/orm/session.py",
 line 2496, in flush
self._flush(objects)
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/orm/session.py",
 line 2637, in _flush
transaction.rollback(_capture_exception=True)
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py",
 line 68, in __exit__
compat.raise_(
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/util/compat.py",
 line 178, in raise_
raise exception
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/orm/session.py",
 line 2597, in _flush
flush_context.execute()
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/orm/unitofwork.py",
 line 422, in execute
rec.execute(self)
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/orm/unitofwork.py",
 line 538, in execute
self.dependency_processor.process_deletes(uow, states)
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/orm/dependency.py",
 line 1104, in process_deletes
self._run_crud(
  File 
"/Users/aquinmx3/venv/espresso3.8/lib/python3.8/site-packages/sqlalchemy/orm/dependency.py",
 line 1201, in _run_crud
raise exc.StaleDataError(
sqlalchemy.orm.exc.StaleDataError: DELETE statement on table 
'mix_child_class_child_child_class' expected to delete 1 row(s); Only 0 were 
matched.
>>>
KeyboardInterrupt

Works when ChildClass is declared as follows instead of as written in original 
question:

class ChildClass(Base):
__tablename__ = "child_class"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid4())
parents = relationship(
"ParentClass",
secondary="mix_parent_class_child_class",
passive_deletes=True,
)
children = relationship(
"ChildChildClass",
secondary="mix_child_class_child_child_class",
cascade="

Re: [sqlalchemy] Re: Can't delete cascade many-to-many with polymorphic relationships unless using lazy=dynamic

2020-12-17 Thread Mark Aquino
They seem to be runnable except the base should be DeclarativeMeta

The relationships aren’t to the same target in real life,

It’s like this:

Class BaseClass:
...

Class SubClassA(BaseClass)
...

Class SubclassB(BaseClass):
...

(Plus Many other subclasses)

A Mixer “BaseClassBaseClass” such that child subclassA and subclassB are both 
present in mix_base_class_bass_class

BaseClass has relationships to BaseClass, SubClassA and SubClassB, so you can 
access only SubClassAs and SubClassBs or all SubClassXs that could be filtered 
to whatever subclass you need. All these relationships use the same mixer 
table, because they all share a primary key with BaseClass (and removing the 
need to make explicit mixed tables for every subclass).

Mark Aquino

From: sqlalchemy@googlegroups.com  on behalf of 
Mike Bayer 
Sent: Thursday, December 17, 2020 7:08:58 PM
To: noreply-spamdigest via sqlalchemy 
Subject: Re: [sqlalchemy] Re: Can't delete cascade many-to-many with 
polymorphic relationships unless using lazy=dynamic

your examples aren't complete or runnable so I don't really know what the issue 
is, although having two relationships to the same target class seems a little 
unusual and I'm not sure why you'd need that.


On Thu, Dec 17, 2020, at 6:01 PM, maqui...@gmail.com<mailto:maqui...@gmail.com> 
wrote:

I think I may have just found a solution? Not sure if this is correct but it 
looks like it worked when i changed the "extra" relationship to 
passive_deletes=True instead of cascade

class ChildClass(XPressoBase):
__tablename__ = "child_class"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid4())
parents = relationship("ParentClass", secondary="mix_parent_class_child_class", 
passive_deletes=True)
children = relationship("ChildChildClass", 
secondary="mix_child_class_child_child_class", cascade="all, delete")
children2 = relationship("ChildChildClass", 
secondary="mix_child_class_child_child_class", passive_deletes=True)
On Thursday, December 17, 2020 at 5:50:06 PM UTC-5 maqui...@gmail.com wrote:
I have a polymorphic data model where association tables are to base classes 
and some relationships that link to different child classes to filter out the 
non-matching base classes, however these seem to result in sqlalchemy being 
unable to delete cascade properly

In a real case lets say i have
class Base():
   children = relationship("Base", secondary="mix_base_base", cascade="all, 
delete")
   someTypes = relationship("SomeType", secondary="mix_base_base", 
cascade="all, delete")
   other_types = relationship("OtherType", secondary="mix_base_base", 
cascade="all")

class SomeType(Base):
parents = relationship("Base", secondary="mix_base_base", 
passive_deletes=True)

class OtherType(Base):
parents = relationship("Base", secondary="mix_base_base", 
passive_deletes=True)


if I delete a base that doesn't have relationships to SomeType and OtherType, 
then everything works great. However once I add those extra relationships 
sqlalchemy no longer deletes the children relationships.  This can be overcome 
by using lazy="dynamic" on the relationships, but at GREAT performance cost 
(about 100%), which isn't good.

Does anyone know how to get around this without using dynamic loading? The 
specific relationships are important for front end pagination of data, but the 
performance cost is too great for the amount of data in this system to double 
the query times.

a simplified and stupid workable example where I just add a redundant children2 
relationship to ChildClass, resulting in the same problem:

from uuid import uuid4

from sqlalchemy import Column
from sqlalchemy.dialects.postgresql.base import UUID
from sqlalchemy.orm import relationship

from webapp.database.orm.base import XPressoBase

class ChildClass(Base):
__tablename__ = "child_class"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid4())
parents = relationship("ParentClass", secondary="mix_parent_class_child_class", 
passive_deletes=True)
children = relationship("ChildChildClass", 
secondary="mix_child_class_child_child_class", cascade="all, delete")
children2 = relationship("ChildChildClass", 
secondary="mix_child_class_child_child_class", cascade="all, delete")

class ChildChildClass(Base):
__tablename__ = "child_child_class"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid4())
parents = relationship("ChildClass", 
secondary="mix_child_class_child_child_class", passive_deletes=True)

class ParentClass(Base):
__tablename__ = "parent_class"
id = Column("id"

Re: [sqlalchemy] ORM AmbiguousForeignKeysErro

2020-09-09 Thread Mark Aquino
It's okay, I misunderstood what to point to in the inherit_condition
argument.  I pointed it to the right column and it's working now.

On Tue, Sep 8, 2020 at 9:37 PM Richard Damon 
wrote:

> On 9/8/20 8:02 PM, Mark Aquino wrote:
> > I’m not using that FK for inheritance though. I’m just relating one
> > type of tracked entity to another (it’s parent, basically). After I
> > did this it actually broke my code so it didn’t really work (it just
> > temporarily got rid of one error and caused a more complicated one)
> >
> I think you need to post the basics of the code. See the link below
> about making it a MCVE
>
> There is obviously something you aren't describing, or we need to see to
> point to you what you are missing.
>
> --
> Richard Damon
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example.  See  http://stackoverflow.com/help/mcve for a full
> description.
> ---
> 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 view this discussion on the web visit
> https://groups.google.com/d/msgid/sqlalchemy/414307fa-8779-5be1-244c-57c1cf9d7a02%40Damon-Family.org
> .
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/CAL6EnB4OL9KjgZeHuL-WPYzgi%2BMMFwvwn%2Bjx%2Br80HSTjBcdLTg%40mail.gmail.com.


Re: [sqlalchemy] ORM AmbiguousForeignKeysErro

2020-09-08 Thread Mark Aquino
So if I’m understanding correctly then the inherit_condition should be the 
column mapping the subclass to the superclass? In my case TrackedEntity.id == 
Request.id?

Mark Aquino

From: sqlalchemy@googlegroups.com  on behalf of 
Mike Bayer 
Sent: Tuesday, September 8, 2020 9:01:53 PM
To: noreply-spamdigest via sqlalchemy 
Subject: Re: [sqlalchemy] ORM AmbiguousForeignKeysErro

the error is raised because there is more than one column on your subclass 
table that is a foreign key to the superclass table.   SQLAlchemy refuses to 
guess which of these columns it should use to create the join condition between 
superclass and subclass table.




On Tue, Sep 8, 2020, at 4:50 PM, maqui...@gmail.com<mailto:maqui...@gmail.com> 
wrote:
I'm having the same problem,
I have a base class called TrackedEntity that has child classes like Request 
and others that inherit from it

on Request I wanted to put a reference to the id of the TrackedEntity that 
created the Request
class Request(TrackedEntity, TrackedEntityContainer, VisibleIdMixin):
 parent_tracked_entity_id = Column(UUID, ForeignKey("tracked_entity.id"))

and I get the same error as above.  Adding that inherit condition makes the 
runtime error stop, but it doesn't make sense to me. Why can't I just have a 
foreign key to that table? It's a simple many to one


@Richard: you can use @declared_attr.cascading to cascade the mapper_args to 
your child classes.
On Friday, August 28, 2020 at 2:56:02 PM UTC-4 Richard Damon wrote:
Thank you, so that go into each subclass that would have the problem.

 8/28/20 2:37 PM, Mike Bayer wrote:
> the argument you're looking for is inherit_condition:
>
> https://docs.sqlalchemy.org/en/13/orm/mapping_api.html#sqlalchemy.orm.mapper.params.inherit_condition
>
>
> class Foo(...):
>__mapper_args__ = {
>   "inherit_condition": node_id == Node.node_id
>}
>

--
Richard Damon



--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example. See http://stackoverflow.com/help/mcve for a full description.
---
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<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/a515b477-5308-4609-af86-c0fb671151cen%40googlegroups.com<https://groups.google.com/d/msgid/sqlalchemy/a515b477-5308-4609-af86-c0fb671151cen%40googlegroups.com?utm_medium=email_source=footer>.


--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example. See http://stackoverflow.com/help/mcve for a full description.
---
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<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/b21d61c4-8221-4274-851f-363b4d098ae6%40www.fastmail.com<https://groups.google.com/d/msgid/sqlalchemy/b21d61c4-8221-4274-851f-363b4d098ae6%40www.fastmail.com?utm_medium=email_source=footer>.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/BL0PR16MB2515D0D6FA4D36D65E1CD708F0260%40BL0PR16MB2515.namprd16.prod.outlook.com.


Re: [sqlalchemy] ORM AmbiguousForeignKeysErro

2020-09-08 Thread Mark Aquino
I’m not using that FK for inheritance though. I’m just relating one type of 
tracked entity to another (it’s parent, basically). After I did this it 
actually broke my code so it didn’t really work (it just temporarily got rid of 
one error and caused a more complicated one)

Mark Aquino

From: sqlalchemy@googlegroups.com  on behalf of 
Richard Damon 
Sent: Tuesday, September 8, 2020 5:10:52 PM
To: sqlalchemy@googlegroups.com 
Subject: Re: [sqlalchemy] ORM AmbiguousForeignKeysErro

The key point is that the derived class needs a pointer to its base
class for the inheritance, and if it has another one to represent object
linkage, then the ORM module doesn't know which one is which, in my case
even though they were all called node_id, the fact one of the classes
had another reference it didn't know which to use, thus you need to put
a __mapper_args__ with an entry for "inherit_condition" to indicate
which on to use for inheritance. Once you resolve the inheritance
problem, the rest can be used for object relationships.

On 9/8/20 4:50 PM, maqui...@gmail.com wrote:
> I'm having the same problem,
> I have a base class called TrackedEntity that has child classes like
> Request and others that inherit from it
>
> on Request I wanted to put a reference to the id of the TrackedEntity
> that created the Request
> class Request(TrackedEntity, TrackedEntityContainer, VisibleIdMixin):
>  parent_tracked_entity_id = Column(UUID,
> ForeignKey("tracked_entity.id"))
>
> and I get the same error as above.  Adding that inherit condition
> makes the runtime error stop, but it doesn't make sense to me. Why
> can't I just have a foreign key to that table? It's a simple many to one
>
>
> @Richard: you can use @declared_attr.cascading to cascade the
> mapper_args to your child classes.
> On Friday, August 28, 2020 at 2:56:02 PM UTC-4 Richard Damon wrote:
>
> Thank you, so that go into each subclass that would have the problem.
>
>  8/28/20 2:37 PM, Mike Bayer wrote:
> > the argument you're looking for is inherit_condition:
> >
> >
> 
> https://docs.sqlalchemy.org/en/13/orm/mapping_api.html#sqlalchemy.orm.mapper.params.inherit_condition
>
> >
> >
> > class Foo(...):
> >__mapper_args__ = {
> >   "inherit_condition": node_id == Node.node_id
> >}
> >
>
> --
> Richard Damon
>

--
Richard Damon

--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
---
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/8f002a3f-fb68-5f8b-c921-2dddaceb1119%40Damon-Family.org.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/BL0PR16MB2515A660D03E6EED26088E6BF0260%40BL0PR16MB2515.namprd16.prod.outlook.com.


[sqlalchemy] helper function to get and/or update the InstrumentedList from a relationship on a model

2020-08-12 Thread Mark Aquino
I was interested in creating a generic helper function to get the 
instrumented list associated with a "RelationshipProperty" for a Model,
you can get the relationship from 
inspect(model).mapper.relationships.items(), but the relationship is just 
the RelationshipProperty object and *not* the InstrumentedList.  I could 
not see a way to get the instrumented list from the relationship and was 
wondering if I was missing something or if we really must use 
getattr(model, property_name) to get the InstrumentedList.

I also noticed that I couldn't directly set the instrumented list values 
from the relationship; I can do add/remove/extend operations on the list 
but not e.g. `relationship = [item1, item2, item3,]`, for that I had to use 
setattr(model, relationship_name, values_array)

Any feedback on my approach or if there is a better way to do this would be 
appreciated!

def type_query(type, id):
type_query = g.session.query(type).filter_by(id=id).one()
return type_query

def get_relationship_from_model(parent_entity, relationship_model):
relationship_label = None
for label, r in inspect(parent_entity).mapper.relationships.items():
if r.entity.class_ == relationship_model:
relationship_label = label
break
relationship = getattr(parent_entity, relationship_label)
return relationship_label, relationship


def update_list(relationship_model, entity_model, operation: str, id_list: 
Optional[List[UUID]] = None):
"""
id list = ids to add or remove from relationship
relationship_type = the `type` of the relationship on entity model, e.g...
entity_model = the model whose relationships are being updated
operation = add or remove
:param id_list:
:param relationship_model:
:param entity_model:
:param operation:
:return:
"""
if not id_list:
return entity_model
# e.g. CvMeasurementAttribute -> cv_measurement_attributes
relationship_label, relationship = 
get_relationship_from_model(parent_entity=entity_model,
   
relationship_model=relationship_model)
entities_to_relate = [
type_query(type=relationship_model, id=id_) for id_ in id_list
]
if operation == "add":
relationship.extend(entities_to_relate)
elif operation == "remove":
for entity in entities_to_relate:
relationship.remove(entity)
else:
setattr(entity_model, relationship_label, entities_to_relate)
return entity_model



-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/323bfe66-3d7d-4fe1-87cf-feb4ca9566bfo%40googlegroups.com.


[sqlalchemy] Re: Presenting a higher-level view of a physical table to the end-user

2020-05-31 Thread Mark Robinson
They will be developers, using Python/SqlAlchemy. Thanks.

On Sunday, 31 May 2020 16:41:33 UTC+1, Jonathan Vanasco wrote:
>
> How will the end-users be querying?  Are they going to be consumers who 
> are submitting params to a form, or are they going to be developers using 
> Python/SqlAlchemy?
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/c0c52306-5de9-4df4-89b6-53f0d5c05283%40googlegroups.com.


[sqlalchemy] Presenting a higher-level view of a physical table to the end-user

2020-05-31 Thread Mark Robinson
Hi there, we are considering using SQLAlchemy, specifically the Core part, 
for our project. I'm guessing we won't need ORM, but we keep an open mind.
One of the things we would like to do is this: after connecting to a 
database (read-only), we would like to present to the end-user a view of a 
given table (or actually a join of tables) as a "view". This won't 
necessarily be an actual database view/table, also given that we don't want 
to modify the database.
For example, say there are two tables (forgive the made-up syntax).

Country(countryCode: string(2), population: Integer, gdp: Float)
City(cityCode: string(3), countryCode: ForeignKey string(2), population: 
Integer, altitude: Integer)

Say I join these and I want to present this schema to the user:
SimplifiedCity(fullCode: string(6), cityPopulation: Integer)
where fullCode is the concatenation of Country.countryCode || '.' || 
City.cityCode, e.g. 'GB.LON'

That way, the users will be able to query SimplifiedCity, with the 
unnecessary details hidden from them, like so:
query = 
select([simplifiedCity.c.cityPopulation]).where(simplifiedCity.c.fullCode 
= 'GB.LON')

Is this possible? I noticed the existence of sqlalchemy-views 
, but I'm guessing that would 
have to be done within a transaction that we then roll back, which doesn't 
sound great. Also, I wonder if there are better, more idiomatic ways.

Thanks!

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/d974d77d-60be-4d52-9e5b-5a6c3208f873%40googlegroups.com.


[sqlalchemy] looking for help building relationship that references an intermediate mixer table

2020-03-20 Thread Mark Aquino
I'd like to create a relationship that joins a table linked to a related 
table on a model:

I have a Vessel class, a Well class, and a Batch class.

Vessel and Well are related via a FK on Well (well.vessel_id) but Batch is 
a many to many relationship with Well, e.g.

Batch(Base):
  id = Column(Integer)

Well(Base):
   id = Column(Integer)
   vessel_id = Column(Integer)
   batches = relationship("Batch", secondary="mix_well_tracked_entity")

Is it possible to make a relationship on Vessel to the Batches linked to 
its wells?

Vessel(Base):
   id = Column(Integer)
   wells = relationship("Well")
   wells_batches = relationship("Batch", ...???)


select * from vessel v join well w on w.vessel_id = v.id join 
mix_well_tracked_entity mix1 on mix1.well_id = w.id join batch b on b.id = 
mix1.tracked_entity_id;

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/54af97fe-9de7-4cb2-a4d9-96b33107c6af%40googlegroups.com.


Re: [sqlalchemy] relationship without using a column value (using table name)?

2020-03-16 Thread Mark Aquino
I guess I could do that: I am using a joined table inheritance schema for 
most of the classes in my data model (and that base table does have an 
entity_type_id) but was trying to link a few "entity_type"s to some of the 
classes that didn't inherit from the base.

The difference in the Django model is that the joined class (Addresses) has 
a parent_id column on it, and this line is key: "*class_.id* == foreign(
remote(Address.parent_id))".  without some column on the parent class to 
map to in the primaryjoin clause the relationship function doesn't seem to 
work.  I don't think the discriminator there is necessary to create 
relationship because there IS a "pseudo foreign key", it just has no 
referential integrity.  A bit of a digression but I can't really tell what 
the where clause part is necessary for tbh (Address.discriminator == 
discriminator). When would class_.id == Address.parent_ id but the class 
name != Address.discriminator?

 It would be nice if you could somehow override it and directly specify how 
to create the relationship with a custom query, but oh well...


On Monday, March 16, 2020 at 1:50:27 PM UTC-4, Mike Bayer wrote:
>
>
>
> On Mon, Mar 16, 2020, at 1:23 PM, Mark Aquino wrote:
>
> Unfortunately none of those recipes work for what I'm trying to 
> accomplish, and the mapper just complains that there is no "unambiguous" 
> foreign key column to map the two classes.
>
> Normal referential integrity rules would dictate that I create a column on 
> the related class that referred to the entity_type.id, but in a 
> non-polymorphic/shared table setting it seems completely unnecessary.: what 
> is the point in having a column on a single table like called 
> "entity_type_id" that has the same value in every row?  
>
> I need the relationship to be constructed by a query that looks like:
>
> select entity_type.*, something.*
> from entity_type, something
> where entity_type.table_name = 'something';
>
>
> would you perhaps want to use joined table inheritance?  that's the kind 
> of query it emits.   however the structure you gave does seem to be 
> equivalent to Django's generic foreign key to me. the "table_name" is 
> known as the "discriminator".   
>
>
>
> or 
> select something.*, (select * from entity_type where 
> entity_type.table_name='something') from something;
>
> Is it impossible to create a relationship like this using sqlalchemy?
>
> sqlalchemy doesn't allow this:
>
> @event.listens_for(GenericEntityTypeMixin, "mapper_configured", 
> propagate=True)
> def setup_listener(mapper, class_):
> discriminator = class_.__tablename__
> class_.comments = relationship(
> "EntityType",
> primaryjoin=
> foreign(remote(EntityType.table_name)) == discriminator
> ,
> viewonly=True
> )
>
> On Saturday, March 14, 2020 at 12:55:03 PM UTC-4, Mike Bayer wrote:
>
> this is called a "Generic foreign key" and it's not really a real 
> relational database pattern.There are a series of examples in 
> https://docs.sqlalchemy.org/en/13/orm/examples.html#module-examples.generic_associations
>  
> that show four different ways to achieve this pattern, one of which is the 
> "generic foreign key" that is for example what Django offers, where the 
> combination of a "discriminator" (here you call it table_name) and an id 
> can link to different source tables.   However there are three other ways 
> given of doing the same thing that all use correct referential integrity. 
>Which one to use depends on how you need to be querying the 
> "entity_type"  table, however all four will store essentially the same 
> information, just in different formats.
>
>
>
>
>
>
>
> On Sat, Mar 14, 2020, at 9:55 AM, Mark Aquino wrote:
>
> Is it possible to create a relationship via the table name as the "foreign 
> key"? I tried playing around with the foreign and remote options and tried 
> utilizing what's described here: 
> https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#non-relational-comparisons-materialized-path
>  but 
> I couldn't get it to work for my case.
>
> I have a table that has entity types and a table_name column, e.g.
>
> class EntityType(Base):
> __tablename__ = "entity_type"
> id = Column(UUID, primary_key=True, server_default=FetchedValue())
> table_name = Column(String, nullable=False)
> prefix = Column(Text, unique=True, nullable=False)
> alt_prefix = Column(Text)
> ui_label = Column(Text, unique=True, nullable=False)
> entry_key = Column(Text, unique=True, nullable=False)
>

Re: [sqlalchemy] relationship without using a column value (using table name)?

2020-03-16 Thread Mark Aquino
Unfortunately none of those recipes work for what I'm trying to accomplish, 
and the mapper just complains that there is no "unambiguous" foreign key 
column to map the two classes.

Normal referential integrity rules would dictate that I create a column on 
the related class that referred to the entity_type.id, but in a 
non-polymorphic/shared table setting it seems completely unnecessary.: what 
is the point in having a column on a single table like called 
"entity_type_id" that has the same value in every row?  

I need the relationship to be constructed by a query that looks like:

select entity_type.*, something.*
from entity_type, something
where entity_type.table_name = 'something';

or 
select something.*, (select * from entity_type where 
entity_type.table_name='something') from something;

Is it impossible to create a relationship like this using sqlalchemy?

sqlalchemy doesn't allow this:

@event.listens_for(GenericEntityTypeMixin, "mapper_configured", propagate=True)
def setup_listener(mapper, class_):
discriminator = class_.__tablename__
class_.comments = relationship(
"EntityType",
primaryjoin=
foreign(remote(EntityType.table_name)) == discriminator
,
viewonly=True
)

On Saturday, March 14, 2020 at 12:55:03 PM UTC-4, Mike Bayer wrote:
>
> this is called a "Generic foreign key" and it's not really a real 
> relational database pattern.There are a series of examples in 
> https://docs.sqlalchemy.org/en/13/orm/examples.html#module-examples.generic_associations
>  
> that show four different ways to achieve this pattern, one of which is the 
> "generic foreign key" that is for example what Django offers, where the 
> combination of a "discriminator" (here you call it table_name) and an id 
> can link to different source tables.   However there are three other ways 
> given of doing the same thing that all use correct referential integrity. 
>Which one to use depends on how you need to be querying the 
> "entity_type"  table, however all four will store essentially the same 
> information, just in different formats.
>
>
>
>
>
>
>
> On Sat, Mar 14, 2020, at 9:55 AM, Mark Aquino wrote:
>
> Is it possible to create a relationship via the table name as the "foreign 
> key"? I tried playing around with the foreign and remote options and tried 
> utilizing what's described here: 
> https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#non-relational-comparisons-materialized-path
>  but 
> I couldn't get it to work for my case.
>
> I have a table that has entity types and a table_name column, e.g.
>
> class EntityType(Base):
> __tablename__ = "entity_type"
> id = Column(UUID, primary_key=True, server_default=FetchedValue())
> table_name = Column(String, nullable=False)
> prefix = Column(Text, unique=True, nullable=False)
> alt_prefix = Column(Text)
> ui_label = Column(Text, unique=True, nullable=False)
> entry_key = Column(Text, unique=True, nullable=False)
>
> config_entity_column_ui_visibility = 
> relationship("ConfigEntityColumnUiVisibility")
>
> def __repr__(self):
> return (
> f" prefix={self.prefix} ui_label={self.ui_label} "
> f"entry_key={self.entry_key}>"
> )
>
>
> I want to create a relationship to this table from other tables via their 
> table name rather than a column on the table.  Is this possible?
>
>
> e.g.
>
> class GenericEntityTypeMixin:
>
> @declared_attr.cascading
> def prefix(cls) -> ColumnProperty:
> from webapp.database.orm.models import EntityType
>
> return column_property(
> select([EntityType.prefix])
> .where(EntityType.table_name == cls.__tablename__)
> .as_scalar(),
> info={"key": "prefix"},
> )
>
> @hybrid_property
> def qualified_id(self):
> return f"{self.prefix}-{self.visible_id}"
>
> 
> *# @declared_attr*
> *# def entity_type(cls) -> RelationshipProperty:*
> *# how do we create relationship without using a column object on the 
> foreign side?*
> @declared_attr
> def entity_type_entry_key(cls):
> return association_proxy("entity_type", "entry_key")
>
>
> --
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/
>  
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
&

[sqlalchemy] relationship without using a column value (using table name)?

2020-03-14 Thread Mark Aquino
Is it possible to create a relationship via the table name as the "foreign 
key"? I tried playing around with the foreign and remote options and tried 
utilizing what's described here: 
https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#non-relational-comparisons-materialized-path
 but 
I couldn't get it to work for my case.

I have a table that has entity types and a table_name column, e.g.

class EntityType(Base):
__tablename__ = "entity_type"

id = Column(UUID, primary_key=True, server_default=FetchedValue())
table_name = Column(String, nullable=False)
prefix = Column(Text, unique=True, nullable=False)
alt_prefix = Column(Text)
ui_label = Column(Text, unique=True, nullable=False)
entry_key = Column(Text, unique=True, nullable=False)

config_entity_column_ui_visibility = 
relationship("ConfigEntityColumnUiVisibility")

def __repr__(self):
return (
f""
)


I want to create a relationship to this table from other tables via their table 
name rather than a column on the table.  Is this possible?


e.g.

class GenericEntityTypeMixin:

@declared_attr.cascading
def prefix(cls) -> ColumnProperty:
from webapp.database.orm.models import EntityType

return column_property(
select([EntityType.prefix])
.where(EntityType.table_name == cls.__tablename__)
.as_scalar(),
info={"key": "prefix"},
)

@hybrid_property
def qualified_id(self):
return f"{self.prefix}-{self.visible_id}"

# @declared_attr
# def entity_type(cls) -> RelationshipProperty:
# how do we create relationship without using a column object on the 
foreign side?

@declared_attr
def entity_type_entry_key(cls):
return association_proxy("entity_type", "entry_key")

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/d54d0af1-7e8e-44f1-8398-989b09b3ea8e%40googlegroups.com.


Re: [sqlalchemy] how to "explicitly" combine columns, for example get the child class value from a query on parent class from same named column?

2020-02-15 Thread Mark Aquino
“You can use a @property so that when you get back an A or a B object , they 
seek to return either the column on A or the column on B.“

I believe you’re describing the behavior I currently have, I.e. if I query B 
then I can get b.visible_id otherwise I get A.visible_id. 

I see your point about efficiency, but I think I’m already doing this sort of 
join under the hood because I’m using GraphQL to query all A and then pulling 
attributes on subclasses of A depending on the type. 

I’m fine with eliminating visible_id from all subclasses, though, but I’d like 
separate numbering for each subclass. 

Is it possible to specify the sequence to use per class when persisting the 
entities or do you have a method for that which you recommend?

If not, can you tell me how to do the mapping with coalesce and I’ll stress 
test it to see if it will work performance wise?

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/2348bb1b-df75-46aa-b43a-458a13d37f99%40googlegroups.com.


Re: [sqlalchemy] Re: SQL expression object expected, got object of type instead

2020-02-14 Thread Mark Wilkins
This seems to be correct, the issue does not occur if I run the exact same 
code locally. Lambda must be doing something, somehow, that is causing 
this. Any advice on how to fix the problem?


On Friday, February 14, 2020 at 9:10:49 AM UTC-5, Mike Bayer wrote:
>
> this looks like something up with the environment or the interpreter.   
> The error message says it got an object whose type() returns 
> "BinaryExpression".   that is exactly the type it is looking for; this 
> class should be a subclass of sqlalchemy.sql.visitors.Visitable.   However 
> for this error to occur, that is suddenly not the case, or the Visitable / 
> BinaryExpression symbol has been modified at runtime, something like 
> that.It's not clear if this could be some artifact of AWS Lambda, or 
> the way the application is doing imports, or something like that.
>
> the approach here would be to make a test program that produces the error 
> under AWS Lambda, then run it in a local Python environment and see if the 
> results are the same or different.
>
> On Fri, Feb 14, 2020, at 5:16 AM, Simon King wrote:
>
> Can you show the real code that runs the query? I'm wondering whether
> the thing that you are comparing against my_table.c.name is not
> actually a simple string.
>
> Simon
>
> On Wed, Feb 12, 2020 at 11:01 PM Mark Wilkins  > wrote:
> >
> > Some additional code incase its relevent:
> >
> > # Get DB connection
> > engine = setup_env_db_engine(debug=True)
> > connection = engine.connect()
> >
> > # Configure SQLalchemy
> > meta = MetaData(bind=engine)
> > meta.reflect()
> >
> > my_table = meta.tables.get('my_table')
> >
> >
> > --
> > SQLAlchemy -
> > The Python SQL Toolkit and Object Relational Mapper
> >
> > http://www.sqlalchemy.org/
> >
> > To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> > ---
> > 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 sqlal...@googlegroups.com .
> > To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/839938dd-ed33-4f55-a836-185ec0689f2f%40googlegroups.com
> .
>
> -- 
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example.  See  http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
> 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 sqlal...@googlegroups.com .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/CAFHwexfyHn5OKiAm8k9QX3R3Gm4xAoZRy7%3Dg33L%3DdO%3DvSDumZg%40mail.gmail.com
> .
>
>
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/5ca02432-e957-412d-91a4-4f4c9dd67f0c%40googlegroups.com.


Re: [sqlalchemy] Re: SQL expression object expected, got object of type instead

2020-02-14 Thread Mark Wilkins
This is the actual code, with table names swapped out. I've confirmed that 
my_table.c.name is infact a column, and the comparison operation generates 
a BinaryExpression object as it is supposed to. The issue is that where() 
throws an exception indicating it doesn't accept BinaryExpression objects, 
even though it is supposed to. 

On Friday, February 14, 2020 at 5:16:40 AM UTC-5, Simon King wrote:
>
> Can you show the real code that runs the query? I'm wondering whether 
> the thing that you are comparing against my_table.c.name is not 
> actually a simple string. 
>
> Simon 
>
> On Wed, Feb 12, 2020 at 11:01 PM Mark Wilkins  > wrote: 
> > 
> > Some additional code incase its relevent: 
> > 
> > # Get DB connection 
> > engine = setup_env_db_engine(debug=True) 
> > connection = engine.connect() 
> > 
> > # Configure SQLalchemy 
> > meta = MetaData(bind=engine) 
> > meta.reflect() 
> > 
> > my_table = meta.tables.get('my_table') 
> > 
> > 
> > -- 
> > SQLAlchemy - 
> > The Python SQL Toolkit and Object Relational Mapper 
> > 
> > http://www.sqlalchemy.org/ 
> > 
> > To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description. 
> > --- 
> > 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 sqlal...@googlegroups.com . 
> > To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/839938dd-ed33-4f55-a836-185ec0689f2f%40googlegroups.com.
>  
>
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/add65511-ec23-4414-a56c-910a2cc3c4ec%40googlegroups.com.


Re: [sqlalchemy] how to "explicitly" combine columns, for example get the child class value from a query on parent class from same named column?

2020-02-14 Thread Mark Aquino
There's no point in really having the visible_id on the A table, other than 
for inheritance.

The point of it being on B (and C, D, E, F, etc.) is that they have unique 
sequences populating those "Visible IDs", so I have can have a B-1 and a 
C-1 and a D-1.

In other words I have my parent table A with 

id, visible_id, type
1, 1, "B"
2, 2, "C"
3, 3, "D"
4, 4, "E"

B
id, visible_id
---
1, 1

C
id, visible_id

2, 1

etc.
The alternative (I suppose) would be somehow configuring A.visible_id to 
use a different sequence for every child class table, although a.) i dont 
know if you can do that and b.) it's less desirable to have duplicate 
values in that column.

On Friday, February 14, 2020 at 12:55:47 PM UTC-5, Simon King wrote:
>
> On Fri, Feb 14, 2020 at 5:35 PM Mark Aquino  > wrote: 
> > 
> > I have a polymorphic class structure like this, with a lot of classes 
> extending the parent class. 
> > In reality I'm using a Mixin that declares the visible_id column and 
> it's defined with @declared_attr.cascading, but for simplicity: 
> > 
> > 
> > 
> > class A(Base): 
> > __tablename__ = 'a' 
> > id = Column(Integer, primary_key=True) 
> >visible_id = Column(Integer) 
> > 
> > class B(A): 
> > __tablename__ = 'b' 
> > id = Column(Integer, ForeignKey("A.id"), primary_key=True) 
> > visible_id = Column(Integer) 
> > 
> > 
> > What I need for my application is to query A.visible_id and return the 
> CHILD values for B.visible_id (and all the others). 
> > 
> > The inheritance works fine, i.e. if i query all As in the database, my 
> response is a list of [B] objects, but unless I directly query B the 
> visible_id from A takes precedence and I cannot query A.visible_id if I 
> remove it from A. 
> > 
> > Can anyone tell me how to configure this? 
> > 
>
> Out of interest, what is the point of having a visible_id column in 
> the B table? I'm having difficulty imagining what it would mean to 
> have an instance of B (which due to inheritance is also an instance of 
> A) which has different values in A.visible_id and B.visible_id. 
>
> Simon 
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/546e5a4a-7ab5-4350-888a-6f8d54fb822c%40googlegroups.com.


Re: [sqlalchemy] how to "explicitly" combine columns, for example get the child class value from a query on parent class from same named column?

2020-02-14 Thread Mark Aquino
There's no point in really having the visible_id on the A table, other than 
for inheritance.

The point of it being on B (and C, D, E, F, etc.) is that they have unique 
sequences populating those "Visible IDs", so I have can have a B-1 and a 
C-1 and a D-1.

In other words I have my parent table A with 

id, visible_id, type
1, 1, "B"
1, 2, "C"
1, 3, "D"
1, 4, "E"

B
id, visible_id
---
1, 1

C
id, visible_id

2, 1

etc.
The alternative (I suppose) would be somehow configuring A.visible_id to 
use a different sequence for every child class table, although a.) i dont 
know if you can do that and b.) it's less desirable to have duplicate 
values in that column.


On Friday, February 14, 2020 at 12:55:47 PM UTC-5, Simon King wrote:
>
> On Fri, Feb 14, 2020 at 5:35 PM Mark Aquino  > wrote: 
> > 
> > I have a polymorphic class structure like this, with a lot of classes 
> extending the parent class. 
> > In reality I'm using a Mixin that declares the visible_id column and 
> it's defined with @declared_attr.cascading, but for simplicity: 
> > 
> > 
> > 
> > class A(Base): 
> > __tablename__ = 'a' 
> > id = Column(Integer, primary_key=True) 
> >visible_id = Column(Integer) 
> > 
> > class B(A): 
> > __tablename__ = 'b' 
> > id = Column(Integer, ForeignKey("A.id"), primary_key=True) 
> > visible_id = Column(Integer) 
> > 
> > 
> > What I need for my application is to query A.visible_id and return the 
> CHILD values for B.visible_id (and all the others). 
> > 
> > The inheritance works fine, i.e. if i query all As in the database, my 
> response is a list of [B] objects, but unless I directly query B the 
> visible_id from A takes precedence and I cannot query A.visible_id if I 
> remove it from A. 
> > 
> > Can anyone tell me how to configure this? 
> > 
>
> Out of interest, what is the point of having a visible_id column in 
> the B table? I'm having difficulty imagining what it would mean to 
> have an instance of B (which due to inheritance is also an instance of 
> A) which has different values in A.visible_id and B.visible_id. 
>
> Simon 
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/6dcc5932-64f4-4aaa-b766-a747d285e132%40googlegroups.com.


[sqlalchemy] how to "explicitly" combine columns, for example get the child class value from a query on parent class from same named column?

2020-02-14 Thread Mark Aquino
I have a polymorphic class structure like this, with a lot of classes 
extending the parent class.  
In reality I'm using a Mixin that declares the visible_id column and it's 
defined with @declared_attr.cascading, but for simplicity:



class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
   visible_id = Column(Integer)

class B(A):
__tablename__ = 'b'
id = Column(Integer, ForeignKey("A.id"), primary_key=True)
visible_id = Column(Integer)


What I need for my application is to query A.visible_id and return the 
CHILD values for B.visible_id (and all the others).

The inheritance works fine, i.e. if i query all As in the database, my 
response is a list of [B] objects, but unless I directly query B the 
visible_id from A takes precedence and I cannot query A.visible_id if I 
remove it from A.

Can anyone tell me how to configure this? 

Thanks!

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/9a248c3e-ec1a-4e18-b663-3a03bab027e5%40googlegroups.com.


Re: [sqlalchemy] Security Implications of Directly Executing Queries Compiled to Strings

2019-03-08 Thread Mark Steward
My understanding is that this is untrusted data, providing a frontend to a
DB, where the "connection" is actually an HTTP API.

I'd be super cautious here, as there are loads of historic encoding issues
with each database backend. Don't forget newlines and null bytes. If you
can, whitelist a subset of characters that are definitely safe, limit
length, validate numbers are in the form you expect. Don't lean on sqla's
escaping because it's not intended for that purpose.

You also need to consider HTTP injection. If it's in a URL, you need to
escape slashes, question marks, etc.



Mark

On Fri, 8 Mar 2019, 18:19 Mike Bayer,  wrote:

> On Fri, Mar 8, 2019 at 10:31 AM Walter Askew  wrote:
> >
> >
> >
> > On Mar 8, 2019, at 5:25 AM, Mike Bayer  wrote:
> >
> >
> > SQL injection has to do with strings that are sent to the database
> > engine.   from what you said above, it seems like you are generating
> > strings just to display them on a webpage?
> >
> >
> > No, I’m not displaying SQL strings on a webpage. I’m asking about the
> safety of directly executing SQL strings returned by .compile() calls, in
> particular when they contain user-provided values.
>
> I've re-read your original request.   If I am reading correctly, *you*
> are generating these values and passing them to an HTTP web service of
> some kind.  In this scenario, there is no untrusted input, so there is
> no security concern. If OTOH you are receiving values *from* an
> HTTP web service that is open to untrusted users, then you need to be
> concerned about security.
>
>
> >
> > that would be the use case
> > for literal_binds.you would not pass these strings to a database
> > engine unless you sanitized all input from the user.
> >
> >
> > I’m asking for more details about the limitations SQLAlchemy has on
> sanitizing user input when compiling strings with literal_binds. The docs
> say things like:
> >
> >  SQLAlchemy has limited ability to do this stringification in certain
> circumstances such as that of emitting DDL. In order to access this
> functionality one can use the literal_binds flag, passed to compile_kwargs:
> >
> > ...
> >
> > the above approach has the caveats that it is only supported for basic
> types, such as ints and strings, and furthermore if a bindparam() witho
> pre-set value is used directly, it won’t be able to stringify that either.
> >
> >
> > and I’m wondering how limited this ability is, what the implications of
> using SQLAlchemy to bind literals rather than going through DBAPI like
> normal are, and if this is an issue if you only try to bind 'basic types,
> such as ints and strings.’
> >
> > I tried testing out a few simple SQL injection examples and saw them get
> quoted out by SQLAlchemy’s literal binding correctly, and I’m wondering how
> safe it is to rely on SQLAlchemy’s literal binding given those warnings in
> the documentation.
> >
> > --
> > SQLAlchemy -
> > The Python SQL Toolkit and Object Relational Mapper
> >
> > http://www.sqlalchemy.org/
> >
> > To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> > ---
> > 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 https://groups.google.com/group/sqlalchemy.
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example.  See  http://stackoverflow.com/help/mcve for a full
> description.
> ---
> 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 https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Re: pandas to MS SQL DataWarehouse (to_sql)

2019-01-31 Thread Mark Pearl
No the error related to this:

sqlalchemy ProgrammingError: (pyodbc.ProgrammingError) ('42000', '[42000]
[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]111214;An attempt to
complete a transaction has failed. No corresponding transaction found.
(111214) (SQLEndTran)') (Background on this error at:
http://sqlalche.me/e/f405)

On Thu, Jan 31, 2019 at 11:02 AM Mike Bayer 
wrote:

> for "dm_exec_sessions" ?  that's an old SQLAlchemy bug that was fixed
> long ago.  see https://github.com/sqlalchemy/sqlalchemy/issues/3994
> please upgrade.
>
> On Wed, Jan 30, 2019 at 10:52 PM  wrote:
> >
> > Any solution for this?
> >
> > On Monday, September 11, 2017 at 6:34:47 PM UTC-4, dirk.biesinger wrote:
> >>
> >> I am encountering errors when trying to use the pd.to_sql function to
> write a dataframe to MS SQL Data Warehouse.
> >> The connection works when NOT using sqlalchemy engines.
> >> I can read dataframes as well as row-by-row via select statements when
> I use pyodbc connections
> >> I can write data via insert statements (as well as delete data) when
> using pyodbc.
> >> However, when I try to connect using a sqlalchemy engine I run into a
> string of error messages starting with:
> >>
> >> ProgrammingError: (pyodbc.ProgrammingError) ('42000', "[42000]
> [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Catalog view
> 'dm_exec_sessions' is not supported in this version. (104385)
> (SQLExecDirectW)")
> >>
> >>
> >> I have searched online, and this exact error seems to have been
> reported / evaluated in May of this year as issue #3994:
> >>
> >>
> >>
> https://bitbucket.org/zzzeek/sqlalchemy/issues/3994/azure-sql-datawarehouse-basic
> >>
> >>
> >> I could not find a solution to this, and I'd really dislike to do a
> line-wise or blob insert statement (I'm working with multiple datasets that
> each has a few million rows, so execution time is a consideration, although
> the result sets I'm getting are more like in the 100k lines area each.)
> >>
> >>
> >> I get the same error messages even when I replace the pd.to_sql command
> with a simple engine.connect()
> >>
> >>
> >> Enclosed my installed packages (packages.list)
> >>
> >> Enclosed the full traceback (traceback.txt)
> >>
> >>
> >> This is the code I'm using:
> >>
> >> connection_string = "mssql+pyodbc://:@.
> database.windows.net
> :/?driver=ODBC+Driver+13+for+SQL+Server"
> >> engn = sqlalchemy.engine.create_engine(connection_string, echo=True)
> >> engn.connect()
> >>
> >>
> >> I'm very well aware that MS SQL DataWarehouse behaves a bit different,
> so I'm open for some experimenting to get this issue narrowed down.
> >>
> >> In case it matters: I'm running an ubuntu 16.04 VM on azure with
> jupyter notebook server and python 3.6.1.
> >>
> >> Best,
> >>
> >> DB
> >
> >
> > Confidentiality Note: This email may contain confidential and/or private
> information.
> > If you received this email in error please delete and notify sender.
> >
> > --
> > SQLAlchemy -
> > The Python SQL Toolkit and Object Relational Mapper
> >
> > http://www.sqlalchemy.org/
> >
> > To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> > ---
> > 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 https://groups.google.com/group/sqlalchemy.
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example.  See  http://stackoverflow.com/help/mcve for a full
> description.
> ---
> 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 https://groups.google.com/group/sqlalchemy.
> For m

Re: [sqlalchemy] sqlalchemy.orm.exc.StaleDataError upon migration from SQLAlchemy 1.1.15 to 1.2.0 or 1.2.1

2018-02-12 Thread Mark Sapiro
On 02/12/2018 01:32 PM, Mike Bayer wrote:
> I've loaded up mailman's test suite and one step at a time reduced the
> failing test to more granular steps, removing one at a time to
> continue to reproduce the error.   It turns out there is a fundamental
> bug in the post_update feature that has existed for years and is only
> becoming apparent now that the feature reports on missed rows.
> issue is at 
> https://bitbucket.org/zzzeek/sqlalchemy/issues/4187/post_update-fails-if-the-parent-object-is.
>   hopefully fixed in a few hours and hopefully backports to 1.1.x
> though it's only critical that it gets to 1.2 since that's where the
> assertion was added.


Thank you very much for following up on this Mike and finding the issue.
I'm sorry I wasn't able to be more help in the isolation process, but
I'm happy it will be fixed.

-- 
Mark Sapiro <m...@msapiro.net>The highway is for gamblers,
San Francisco Bay Area, Californiabetter use your sense - B. Dylan

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] sqlalchemy.orm.exc.StaleDataError upon migration from SQLAlchemy 1.1.15 to 1.2.0 or 1.2.1

2018-01-21 Thread Mark Sapiro


On Sunday, January 21, 2018 at 6:51:29 AM UTC-8, Mike Bayer wrote:
>
> here are a few questions: 
>
> 1. is mailman using the version_id mapper feature with these mappings ? 
>
> 2. do mailman mappings use natural primary keys?  in the above example 
> are the primary keys of objects changing



Mike,

Thank you for the replies. I will not be able to follow up for a while as I 
have an out-of-town guest arriving this evening for a week, but I will ask 
the other Mailman developers to review this thread, and someone will follow 
up.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] sqlalchemy.orm.exc.StaleDataError upon migration from SQLAlchemy 1.1.15 to 1.2.0 or 1.2.1

2018-01-20 Thread Mark Sapiro
Gnu Mailman 3 uses SQL Alchemy to access SQL databases. We have an issue 
with one of or unit tests which passes with  SQLAlchemy <= 1.1.15 but which 
fails with SQLAlchemy >= 1.2. The failure is independent of the backend 
(sglite, mysql or pgsql). Here's a traceback from the failure.

Traceback (most recent call last):
  File "/builds/mailman/mailman/src/mailman/model/tests/test_user.py", line 
184, in test_absorb_memberships
all_users = list(self._manager.users)
  File "/builds/mailman/mailman/src/mailman/model/usermanager.py", line 102, in 
users
yield from store.query(User).order_by(User.id).all()
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/query.py",
 line 2726, in all
return list(self)
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/query.py",
 line 2877, in __iter__
self.session._autoflush()
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
 line 1434, in _autoflush
self.flush()
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
 line 2243, in flush
self._flush(objects)
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
 line 2369, in _flush
transaction.rollback(_capture_exception=True)
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py",
 line 66, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/util/compat.py",
 line 187, in reraise
raise value
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/session.py",
 line 2333, in _flush
flush_context.execute()
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py",
 line 391, in execute
rec.execute(self)
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py",
 line 542, in execute
persistence.post_update(self.mapper, states, uow, cols)
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/persistence.py",
 line 234, in post_update
mapper, table, update)
  File 
"/builds/mailman/mailman/.tox/py36-nocov/lib/python3.6/site-packages/sqlalchemy/orm/persistence.py",
 line 982, in _emit_post_update_statements
(table.description, len(records), rows))
sqlalchemy.orm.exc.StaleDataError: UPDATE statement on table 'user' expected to 
update 1 row(s); 0 were matched.


The test that fails sets up 3 mailing lists and subscribes 2 users (Anne 
and Bart) to some or all of the lists with different roles. Then user Anne 
"absorbs" user Bart so user Bart is deleted and user Anne assumes all 
Bart's memberships. The actual code in the test may not be intelligible 
without more Mailman knowledge, but it is:
def test_absorb_memberships(self):
# When a user is absorbed, all of their user-subscribed memberships
# are relinked to the absorbing user.
mlist2 = create_list('te...@example.com')
mlist3 = create_list('te...@example.com')
with transaction():
# This has to happen in a transaction so that both the user and
# the preferences objects get valid ids.
bart = self._manager.create_user('b...@example.com', 'Bart 
Person')
set_preferred(bart)
# Subscribe both users to self._mlist.
self._mlist.subscribe(self._anne, MemberRole.member)
self._mlist.subscribe(bart, MemberRole.moderator)
# Subscribe only Bart to mlist2.
mlist2.subscribe(bart, MemberRole.owner)
# Subscribe only Bart's address to mlist3.
mlist3.subscribe(bart.preferred_address, MemberRole.moderator)
# There are now 4 memberships, one with Anne two with Bart's user 
and
# one with Bart's address.
all_members = list(self._manager.members)
self.assertEqual(len(all_members), 4, all_members)
# Do the absorption.
self._anne.absorb(bart)
# The Bart user has been deleted, leaving only the Anne user in the
# user manager.
all_users = list(self._manager.users)
self.assertEqual(len(all_users), 1)
self.assertEqual(all_users[0], self._anne)
# There are no leftover memberships for user Bart.  Anne owns all 
the
# memberships.
all_members = list(self._manager.members)
self.assertEqual(len(all_members), 4, all_members)
self.assertEqual(self._anne.memberships.member_count, 4)
memberships = {(member.list_id, member.role): member
   for member in self._anne.memberships.members}
# Note that Anne is now both a member and moderator of the test 
list.
self.assertEqual(set(memberships), set([

[sqlalchemy] Re: .one is not returning a KeyedTuple, but a

2017-04-25 Thread Mark Jones

I'm keying off hasattr(obj, 'keys') which is working.  Still seems strange 
that it is returning a non-exported class though.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] .one is not returning a KeyedTuple, but a

2017-04-24 Thread Mark Jones
We are upgrading from 0.9.7 to 1.1.9 and I've run into a bit of a problem 
with the upgrade.

I have a query which  is based on a .select_from() and .join() so the 
mapping doesn't really exist from a single model.  All of the fields have 
labels though and the result set produces the right results.  The problem 
comes from the return type of the results:

def one_or_none(self):
ret = list(self)

l = len(ret)
if l == 1:
return ret[0]
elif l == 0:
return None
else:
raise orm_exc.MultipleResultsFound("Multiple rows were found 
for one_or_none()")
 
When it returns ret[0] is not returning an exported sqlalchemy type. 
 Before it would return a KeyedTuple or based on some of our code maybe 
even a RowProxy which we would use to control serialization to json for the 
response to the client.  However, this new type is NOT a KeyTuple and 
therefore isinstance(obj, KeyedTuple) returns False and then our code 
fails.  isinstance(obj, AbstractKeyedTuple) does return True, but that 
isn't one of the exported classes from sqlalchemy.util.  isinstance(obj, 
_LW) returns True as well, but the same objections affect that type as well

The actual class looks like:

>>> obj.__class__


I could fix this by simply importing it from _collections, but that doesn't 
seem like the right solution.  So, I'm wondering if this is a bug or if I'm 
just looking at the problem wrong.  I could pick up on the presence of the 
keys() method and use that, but what if that conflicts with a field in the 
db.

A shortened version of the query looks like this:
return db.query(Account.name.label('account_name'),
Account.id.label('id'),
Account.id.label('account_id'),

select([func.coalesce(func.sum(...).as_scalar().label('count'),
not_(Account.disabled).label('enabled'),
AccountStatus.name.label('account_status'),
User.login,
User.first_name,
User.last_name,
 .select_from(Account)\
 .join(User, User.id == Account.primary_user_id)\
 .join(AccountStatus, Account.account_status_id == 
AccountStatus.id)\
 .outerjoin(account_manager, 
Account.account_manager_user_id == account_manager.id)

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Re: SQLAlchemy & Teradata

2016-12-06 Thread Mark Sandan
There is also a tutorial 
here 
https://developer.teradata.com/tools/articles/teradata-sqlalchemy-introduction

It's a hands on way of getting started with SQLAlchemy but using the 
Teradata Dialect. I wrote it in such a way so that the details of the 
dialect aren't that significant so hopefully it is also useful to other 
SQLAlchemy noobs like myself!

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] SQLAlchemy & Teradata

2016-11-30 Thread Mark Sandan
Hello group, I'd like to announce a dialect for the Teradata database!

I'm still learning a lot about SQLAlchemy and ORMs in general. The dialect 
isn't "production" ready per se but it provides a functioning base for 
future Dialects against Teradata. 

I have a gitter: https://gitter.im/sandan/sqlalchemy-teradata for your 
comments, questions, and suggestions. 
Please feel free to open issues/bugs and pull 
requests: https://github.com/Teradata/sqlalchemy-teradata

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Dialects supporting autocommit in the current session

2016-09-27 Thread Mark Sandan
Thanks! I'll check it out. I wanted to write an application that made sure 
to autocommit for various database backends or else if those backends 
already support it, then don't autocommit. I will check out 
the set_isolation_level() method.

On Tuesday, September 27, 2016 at 7:34:29 AM UTC-7, Mike Bayer wrote:
>
>
> On 09/26/2016 09:25 PM, Mark Sandan wrote: 
> > Hi, 
> >   I was wondering if there exists a dialect-wide way to query whether 
> > the underlying database is in a transaction mode that requires an 
> > autocommit or not. In Teradata, there is this notion of a transaction 
> > mode. When a session in Teradata is in a certain transaction mode 
> > (TDBS), autocommits are used (the COMMIT is implicit). Alternatively, 
> > when in ANSI mode, a COMMIT must explicitly be specified for the end of 
> > a transaction (or ROLLBACK or ABORT). I'm wondering if it would be 
> > useful to have something like below in the Dialect interface: 
>
> SQLAlchemy's support for "autocommit" at the DBAPI level is via the 
> set_isolation_level() method which internally will set a DBAPI level 
> conn.autocommit flag if that's how the DBAPI needs it to happen.  It is 
> only supported by Postgresql and MySQL.  But none of these "require" 
> autocommit, it's a flag the user can set, so I'm not sure what you're 
> asking. 
>
> > 
> > | 
> > defconn_supports_autocommit(self,connection,**kw): 
> >""" 
> >returns true if the current underlying database session autocommits 
> > else false 
> >""" 
> > | 
> > 
> > Or if there is already something that effectively does this. 
> > 
> > Thanks! 
> > 
> > -- 
> > 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+...@googlegroups.com  
> > <mailto:sqlalchemy+unsubscr...@googlegroups.com >. 
> > To post to this group, send email to sqlal...@googlegroups.com 
>  
> > <mailto:sqlal...@googlegroups.com >. 
> > Visit this group at https://groups.google.com/group/sqlalchemy. 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Dialects supporting autocommit in the current session

2016-09-26 Thread Mark Sandan
Hi,
  I was wondering if there exists a dialect-wide way to query whether the 
underlying database is in a transaction mode that requires an autocommit or 
not. In Teradata, there is this notion of a transaction mode. When a 
session in Teradata is in a certain transaction mode (TDBS), autocommits 
are used (the COMMIT is implicit). Alternatively, when in ANSI mode, a 
COMMIT must explicitly be specified for the end of a transaction (or 
ROLLBACK or ABORT). I'm wondering if it would be useful to have something 
like below in the Dialect interface:

def conn_supports_autocommit(self, connection, **kw):
   """
   returns true if the current underlying database session autocommits else 
false
   """

Or if there is already something that effectively does this.

Thanks!

-- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Create Table DDL options before "("

2016-05-23 Thread Mark Sandan
No worries, I'll put up a reference to the PR and gerrit proposal in case 
anybody wants to chime in. The change is proposed in git PR #275 
<https://github.com/zzzeek/sqlalchemy/pull/275> and in gerrit 
<https://gerrit.sqlalchemy.org/#/c/85/1> (which I'm still getting used too).


On Sunday, May 22, 2016 at 8:23:14 PM UTC-7, Mike Bayer wrote:
>
> OK so we'll probably just add the hook you've proposed. 
>
> I've not had anytime to work on a computer for like five days straight 
> which puts me super behind, ill try to get to your PR soon. 
>
>
> On 05/19/2016 01:08 PM, Mark Sandan wrote: 
> > Sure, the Teradata database has create table ddl where you can specify 
> > certain options that are separated by commas. We have a reference manual 
> > available online specifying the full DDL here 
> > <
> https://www.google.com/url?sa=t=j==s=web=1=rja=8=0ahUKEwjZkreizubMAhVIXh4KHWp0DrAQFggdMAA=http%3A%2F%2Ftunweb.teradata.ws%2Ftunstudent%2FTeradataUserManuals%2FSQL_Reference_--_Data_Definition_Syntax_Example.pdf=AFQjCNFEIVA1TfbRXNV_hQfCVNBe7gZt3g=dPP1GmBUBEyB186Pkh6HmA>
>  
> (see 
> > page 383 for the full syntax).  Here is some example DDL: 
> > 
> > | 
> > CREATE TABLE t1 ,FALLBACK , 
> >  NO BEFORE JOURNAL, 
> >  NO AFTER JOURNAL, 
> >  CHECKSUM = DEFAULT, 
> >  DEFAULT MERGEBLOCKRATIO 
> >  ( 
> >   c1 VARCHAR(128) NOT NULL, 
> >   Id BYTE(4) NOT NULL, 
> >   OwnerId BYTE(4) NOT NULL 
> >  ) 
> >UNIQUE PRIMARY INDEX ( c1 ) 
> >  UNIQUE INDEX ( Id ); 
> > | 
> > 
> > 
> > 
> > On Thursday, May 19, 2016 at 8:31:49 AM UTC-7, Mike Bayer wrote: 
> > 
> > saw your pull request, just curious what database / DDL is this? 
>  Just 
> > like to see the finished product that you're going for. 
> > 
> > 
> > 
> > On 05/18/2016 09:19 PM, Mark Sandan wrote: 
> > > Hi, I'm implementing a dialect for sqlalchemy and would like to 
> add 
> > > options before the '(' but after the table name in visit_create. I 
> > know 
> > > I can just subclass visit_create in my ddl compiler but it seems 
> > kind of 
> > > silly since I'd be making a small change. Something like the 
> > following: 
> > > | 
> > > 
> > > 
> > > defvisit_create_table(self,create): 
> > >   table =create.element 
> > >   preparer =self.preparer 
> > > 
> > >   text ="\nCREATE " 
> > >   iftable._prefixes: 
> > >  text +=" ".join(table._prefixes)+" " 
> > >   text +="TABLE "+preparer.format_table(table)+" 
> > "+table_options(table)+" (" 
> > > 
> > > | 
> > > 
> > > table_options would be a function in the ddl compiler provided by 
> the 
> > > dialect that takes dialect specific keywords and simply appends 
> comma 
> > > delimited values. I essentially need something like the 'prefixes' 
> > > keyword in Table but for after the table name and before the left 
> > > parens. Any ideas? 
> > > 
> > > -- 
> > > 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+...@googlegroups.com  
> > > <mailto:sqlalchemy+unsubscr...@googlegroups.com  
> >. 
> > > To post to this group, send email to sqlal...@googlegroups.com 
> >  
> > > <mailto:sqlal...@googlegroups.com >. 
> > > Visit this group at https://groups.google.com/group/sqlalchemy 
> > <https://groups.google.com/group/sqlalchemy>. 
> > > For more options, visit https://groups.google.com/d/optout 
> > <https://groups.google.com/d/optout>. 
> > 
> > -- 
> > 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+...@googlegroups.com  
> > <mailto:sqlalchemy+unsubscr...@googlegroups.com >. 
> > To post to this group, send email to sqlal...@googlegroups.com 
>  
> > <mailto:sqlal...@googlegroups.com >. 
> > Visit this group at https://groups.google.com/group/sqlalchemy. 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Re: Is there a good doc page/tutorial for writing a dialect?

2016-05-20 Thread Mark Sandan
 I recommend Mike's article from the open source architecture book 
. It helped me understand where 
dialects fall in relation to the other SQLAlchemy components and it 
provided a great overview in general. I bootstrapped off of what other 
dialects did and tried to implement as much as I could to get enough 
functionality from the Core tutorial 
 working. Hope it 
helps.

On Thursday, May 19, 2016 at 2:20:57 PM UTC-7, John Omernik wrote:
>
> I am trying to write a new dialect, and while many things are fairly 
> obvious, many are also not. It would be helpful to point to some docs on 
> how the dialect writing works, what events/methods we can overwrite and 
> what it can help us do. 
>
>
> Thanks!
>
> John
>

-- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Create Table DDL options before "("

2016-05-19 Thread Mark Sandan
Sure, the Teradata database has create table ddl where you can specify 
certain options that are separated by commas. We have a reference manual 
available online specifying the full DDL here 
<https://www.google.com/url?sa=t=j==s=web=1=rja=8=0ahUKEwjZkreizubMAhVIXh4KHWp0DrAQFggdMAA=http%3A%2F%2Ftunweb.teradata.ws%2Ftunstudent%2FTeradataUserManuals%2FSQL_Reference_--_Data_Definition_Syntax_Example.pdf=AFQjCNFEIVA1TfbRXNV_hQfCVNBe7gZt3g=dPP1GmBUBEyB186Pkh6HmA>
 (see 
page 383 for the full syntax).  Here is some example DDL:

CREATE TABLE t1 ,FALLBACK ,
 NO BEFORE JOURNAL,
 NO AFTER JOURNAL,
 CHECKSUM = DEFAULT,
 DEFAULT MERGEBLOCKRATIO
 (
  c1 VARCHAR(128) NOT NULL,
  Id BYTE(4) NOT NULL,
  OwnerId BYTE(4) NOT NULL
 )
   UNIQUE PRIMARY INDEX ( c1 )
 UNIQUE INDEX ( Id );



On Thursday, May 19, 2016 at 8:31:49 AM UTC-7, Mike Bayer wrote:
>
> saw your pull request, just curious what database / DDL is this?  Just 
> like to see the finished product that you're going for. 
>
>
>
> On 05/18/2016 09:19 PM, Mark Sandan wrote: 
> > Hi, I'm implementing a dialect for sqlalchemy and would like to add 
> > options before the '(' but after the table name in visit_create. I know 
> > I can just subclass visit_create in my ddl compiler but it seems kind of 
> > silly since I'd be making a small change. Something like the following: 
> > | 
> > 
> > 
> > defvisit_create_table(self,create): 
> >   table =create.element 
> >   preparer =self.preparer 
> > 
> >   text ="\nCREATE " 
> >   iftable._prefixes: 
> >  text +=" ".join(table._prefixes)+" " 
> >   text +="TABLE "+preparer.format_table(table)+" 
> "+table_options(table)+" (" 
> > 
> > | 
> > 
> > table_options would be a function in the ddl compiler provided by the 
> > dialect that takes dialect specific keywords and simply appends comma 
> > delimited values. I essentially need something like the 'prefixes' 
> > keyword in Table but for after the table name and before the left 
> > parens. Any ideas? 
> > 
> > -- 
> > 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+...@googlegroups.com  
> > <mailto:sqlalchemy+unsubscr...@googlegroups.com >. 
> > To post to this group, send email to sqlal...@googlegroups.com 
>  
> > <mailto:sqlal...@googlegroups.com >. 
> > Visit this group at https://groups.google.com/group/sqlalchemy. 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Create Table DDL options before "("

2016-05-18 Thread Mark Sandan
Hi, I'm implementing a dialect for sqlalchemy and would like to add options 
before the '(' but after the table name in visit_create. I know I can just 
subclass visit_create in my ddl compiler but it seems kind of silly since 
I'd be making a small change. Something like the following:


def visit_create_table(self, create): 
  table = create.element
  preparer = self.preparer
 
  text = "\nCREATE "
  if table._prefixes:
 text += " ".join(table._prefixes) + " "
  text += "TABLE " + preparer.format_table(table)+ " " + table_options(table
) + " ("


table_options would be a function in the ddl compiler provided by the 
dialect that takes dialect specific keywords and simply appends comma 
delimited values. I essentially need something like the 'prefixes' keyword 
in Table but for after the table name and before the left parens. Any ideas?

-- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Re: Quick way to deep copy an object?

2015-11-30 Thread Mark Sternig
I am in need of doing something similar (a deep copy of related objects). 
Has anyone embarked on this adventure yet and mind sharing any tips, code, 
etc? My use case is to copy a retail Order, and all OrderLineItems, 
OrderNotes, OrderStatus, etc. Thank you in advance for any help.

On Wednesday, September 10, 2008 at 11:56:37 AM UTC-5, picoplex wrote:
>
> Michael,
>
> I get the idea thanks.
>
> Before I embarked on this - I wanted to check that there was not a simple 
> way that I had overlooked.
>
> Thanks for your time.
>
> Regards,
>
> Tim
>
> 2008/9/10 Michael Bayer 
>
>>
>>
>> On Sep 10, 2008, at 4:39 AM, Tim Jones wrote:
>>
>> > Michael,
>> >
>> > Thanks for your reply.
>> >
>> > The use case is configuration management.
>> >
>> > We have complex (SQLAlchemy) objects with many relationships which
>> > we wish to up-version, i.e. we want an exact persistent copy
>> > (attribute values and relationships) of the original object, but
>> > with a different identity, which we will then modify.
>> >
>> > The original object and all its relationships should remain
>> > unchanged (other than a relationship to its successor version).
>> >
>> > We would want the copied object and all its relationships saved to
>> > the database before making changes to it.
>>
>> You'd build a copy function of your own which iterates through
>> attributes and creates new instances.   How you go about locating the
>> attributes to be copied depends on if you want only SQLAlchemy-
>> instrumented attributes, or other attributes as well which are not
>> known to SQLAlchemy.
>>
>> To get a list of all SQLAlchemy attributes for a class, use this
>> expression:
>>
>> [p.key for p in class_mapper(class).iterate_properties]
>>
>> you might want to exclude primary key mappings:
>>
>> pk_keys = set([c.key for c in class_mapper(class).primary_key])
>>
>> [p.key for p in class_mapper(class).iterate_properties if p.key not in
>> pk_keys]
>>
>> the value for each attribute can be retrieved from an instance using
>> getattr(instance, key), and you can construct new instances without
>> calling __init__ by saying class.__new__(class).
>>
>> maybe someone here can flesh this out for me, im a little busy today
>>
>>
>>
>>
>>
>

-- 
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.


Re: [sqlalchemy] Objects inadvertently being added to session

2015-06-15 Thread T Mark
Hi Mike,

Thanks so much for the reply and the pointer.

Since I never added anything to the session explicitly, I think I was 
missing that loading an object implicitly adds that object to the session - 
which does make sense.

Is that right ?

thanks again,
terry


On Monday, June 15, 2015 at 11:26:39 AM UTC-4, Michael Bayer wrote:

  

 On 6/15/15 11:12 AM, T Mark wrote:
  
 Hi there, 

  I have been pulling my hair out on this one.

  I understood that objects make it into the session only due to an 
 explicit call to add().  
  
 or if they are associated with a parent object that is added to the 
 Session via add(), or if they are associated with an object that is already 
 present in a Session via add(); this also will occur for backrefs, e.g. A 
 is in the session, B.a is referred to A, B.a has a backref A.bs, therefore 
 B is now added.   This is configurable.


  But, I seem to be seeing objects being added without my explicitly doing 
 so.  Is this to be expected ?
  

 yes.  please see: 
 http://docs.sqlalchemy.org/en/rel_1_0/orm/cascades.html?highlight=cascades


  
  For instance, I want to establish a many-to-many relationship between 
 two classes: say, for the purposes here, Person and Kid.

  
 test= create table persons (id SERIAL NOT NULL);
 test= CREATE TABLE person_to_kids (person_id INT NOT NULL, kid_id INT 
 NOT NULL);
 test= create table kids (id SERIAL NOT NULL, name TEXT NOT NULL);
 test= insert into  kids (name) VALUES ('Fred');
 test= insert into  kids (name) VALUES ('Barney');

 person_to_kids = Table('person_to_kids',
 Base.metadata,
 Column('person_id', Integer, ForeignKey('
 persons.id')),
 Column('kid_id', Integer, ForeignKey('kids.id')))
 class Person(Base):

  __tablename__ = 'persons'
 id = Column('id', Integer, primary_key = True)
 def __init__(self,
  kids = []):

  kids = Kid.get_kids(kid_names = kids)

  print(__init__ before kids assignment)
 print(session.new)

  Assigning to self.kids here seems to add self to session ??? 
 

  self.kids=kids
 print(After assignment to self.kids)
 print(session.new)

  
  class Kid(Base):
 __tablename__ = 'kids'
 id = Column(Integer, primary_key = True)
 name = Column(String)
 parents = relationship(Person,
secondary = person_to_kids,
backref=kids)

  def __init__(self, name = None):
 self.name = name

  @staticmethod
 def get_kids(kid_names = []):

  kids = []

  for name in kid_names:
 # find first kid
 target_set = session.query(Kid).filter(Kid.name == 
 name).first()
 kids.append(target_set)

  return kids



  What is puzzling me is that, if I have a collection of Kid objects, and 
 I assign it to the kids collection in a Person, the Person object seems to 
 be automatically added to the session and marked as pending, even if I have 
 not added it. 

  For instance, if the Persons table is empty:

   test= select * from persons;
  id
 
 (0 rows)

   

  and I run the following code:
  
print(session.new)
 obj = Person(kids = ['Barney', 'Fred'])
 print(obj has been created)
 print(session.new)
 session.commit()

   
 The output shows that the Person object is added immediately after the 
 assignment to obj.kids, without any call to session.add() anywhere in the 
 code:

   IdentitySet([])
  __init__ before kids assignment
 IdentitySet([])
 After assignment to self.kids
 IdentitySet([__main__.Person object at 0x7fb6ce447b10])
 obj has been created
 IdentitySet([__main__.Person object at 0x7fb6ce447b10])

  
 And indeed, due to the commit() at the end, the person object makes it 
 into the database:

   test= select * from persons;
  id
 
  10
 (1 row)

   

  But, I understood that objects (only) make it into a session by virtue 
 of being explicitly added.
  
 So, is this the correct behavior, or am I misunderstanding something ?

  If I'm not misunderstanding this all, the complete code is at 
 https://github.com/NuggyBuggy/sqlalchemy_question.git .
  
  Thanks for reading,
 terry
  -- 
 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+...@googlegroups.com javascript:.
 To post to this group, send email to sqlal...@googlegroups.com 
 javascript:.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/d/optout.


  

-- 
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

[sqlalchemy] Re: Objects inadvertently being added to session

2015-06-15 Thread T Mark
I forgot to mention:

I'm using:
- Python 2.7.6 on Linux, 
- SQLAlchemy version 0.9.9.
- PostgreSQL 9.3

Thanks -
terry

On Monday, June 15, 2015 at 11:12:54 AM UTC-4, T Mark wrote:

 Hi there,

 I have been pulling my hair out on this one.

 I understood that objects make it into the session only due to an explicit 
 call to add().  But, I seem to be seeing objects being added without my 
 explicitly doing so.  Is this to be expected ?

 For instance, I want to establish a many-to-many relationship between two 
 classes: say, for the purposes here, Person and Kid.


 test= create table persons (id SERIAL NOT NULL);
 test= CREATE TABLE person_to_kids (person_id INT NOT NULL, kid_id INT 
 NOT NULL);
 test= create table kids (id SERIAL NOT NULL, name TEXT NOT NULL);
 test= insert into  kids (name) VALUES ('Fred');
 test= insert into  kids (name) VALUES ('Barney');

 person_to_kids = Table('person_to_kids',
 Base.metadata,
 Column('person_id', Integer, ForeignKey('
 persons.id')),
 Column('kid_id', Integer, ForeignKey('kids.id')))
 class Person(Base):

 __tablename__ = 'persons'
 id = Column('id', Integer, primary_key = True)
 def __init__(self,
  kids = []):

 kids = Kid.get_kids(kid_names = kids)

 print(__init__ before kids assignment)
 print(session.new)

  Assigning to self.kids here seems to add self to session ??? 
 

 self.kids=kids
 print(After assignment to self.kids)
 print(session.new)


 class Kid(Base):
 __tablename__ = 'kids'
 id = Column(Integer, primary_key = True)
 name = Column(String)
 parents = relationship(Person,
secondary = person_to_kids,
backref=kids)

 def __init__(self, name = None):
 self.name = name

 @staticmethod
 def get_kids(kid_names = []):

 kids = []

 for name in kid_names:
 # find first kid
 target_set = session.query(Kid).filter(Kid.name == 
 name).first()
 kids.append(target_set)

 return kids



 What is puzzling me is that, if I have a collection of Kid objects, and I 
 assign it to the kids collection in a Person, the Person object seems to be 
 automatically added to the session and marked as pending, even if I have 
 not added it. 

 For instance, if the Persons table is empty:

 test= select * from persons;
  id
 
 (0 rows)



 and I run the following code:

 print(session.new)
 obj = Person(kids = ['Barney', 'Fred'])
 print(obj has been created)
 print(session.new)
 session.commit()


 The output shows that the Person object is added immediately after the 
 assignment to obj.kids, without any call to session.add() anywhere in the 
 code:

 IdentitySet([])
 __init__ before kids assignment
 IdentitySet([])
 After assignment to self.kids
 IdentitySet([__main__.Person object at 0x7fb6ce447b10])
 obj has been created
 IdentitySet([__main__.Person object at 0x7fb6ce447b10])


 And indeed, due to the commit() at the end, the person object makes it 
 into the database:

 test= select * from persons;
  id
 
  10
 (1 row)



 But, I understood that objects (only) make it into a session by virtue of 
 being explicitly added.

 So, is this the correct behavior, or am I misunderstanding something ?

 If I'm not misunderstanding this all, the complete code is at 
 https://github.com/NuggyBuggy/sqlalchemy_question.git .

 Thanks for reading,
 terry


-- 
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] Objects inadvertently being added to session

2015-06-15 Thread T Mark
Hi there,

I have been pulling my hair out on this one.

I understood that objects make it into the session only due to an explicit 
call to add().  But, I seem to be seeing objects being added without my 
explicitly doing so.  Is this to be expected ?

For instance, I want to establish a many-to-many relationship between two 
classes: say, for the purposes here, Person and Kid.


test= create table persons (id SERIAL NOT NULL);
test= CREATE TABLE person_to_kids (person_id INT NOT NULL, kid_id INT NOT 
NULL);
test= create table kids (id SERIAL NOT NULL, name TEXT NOT NULL);
test= insert into  kids (name) VALUES ('Fred');
test= insert into  kids (name) VALUES ('Barney');

person_to_kids = Table('person_to_kids',
Base.metadata,
Column('person_id', Integer, 
ForeignKey('persons.id')),
Column('kid_id', Integer, ForeignKey('kids.id')))
class Person(Base):

__tablename__ = 'persons'
id = Column('id', Integer, primary_key = True)
def __init__(self,
 kids = []):

kids = Kid.get_kids(kid_names = kids)

print(__init__ before kids assignment)
print(session.new)

 Assigning to self.kids here seems to add self to session ??? 

self.kids=kids
print(After assignment to self.kids)
print(session.new)


class Kid(Base):
__tablename__ = 'kids'
id = Column(Integer, primary_key = True)
name = Column(String)
parents = relationship(Person,
   secondary = person_to_kids,
   backref=kids)

def __init__(self, name = None):
self.name = name

@staticmethod
def get_kids(kid_names = []):

kids = []

for name in kid_names:
# find first kid
target_set = session.query(Kid).filter(Kid.name == name).first()
kids.append(target_set)

return kids



What is puzzling me is that, if I have a collection of Kid objects, and I 
assign it to the kids collection in a Person, the Person object seems to be 
automatically added to the session and marked as pending, even if I have 
not added it. 

For instance, if the Persons table is empty:

test= select * from persons;
 id

(0 rows)



and I run the following code:

print(session.new)
obj = Person(kids = ['Barney', 'Fred'])
print(obj has been created)
print(session.new)
session.commit()


The output shows that the Person object is added immediately after the 
assignment to obj.kids, without any call to session.add() anywhere in the 
code:

IdentitySet([])
__init__ before kids assignment
IdentitySet([])
After assignment to self.kids
IdentitySet([__main__.Person object at 0x7fb6ce447b10])
obj has been created
IdentitySet([__main__.Person object at 0x7fb6ce447b10])


And indeed, due to the commit() at the end, the person object makes it into 
the database:

test= select * from persons;
 id

 10
(1 row)



But, I understood that objects (only) make it into a session by virtue of 
being explicitly added.

So, is this the correct behavior, or am I misunderstanding something ?

If I'm not misunderstanding this all, the complete code is 
at https://github.com/NuggyBuggy/sqlalchemy_question.git .

Thanks for reading,
terry

-- 
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] Is it possible to create a filter 'string' LIKE column + '%'?

2014-04-10 Thread Mark Bird
I can't seem to find a way to do this without passing raw SQL to .filter()

I could just do:

.filter(column == func.substring('string', 1, func.char_length(column)))

but is it possible to do it with LIKE?

I.e. I need to return all rows that match the beginning of a string, so for 
'string' I could match 's', 'st', 'str', etc.

Thanks,

Mark.


-- 
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.


Re: [sqlalchemy] Is it possible to create a filter 'string' LIKE column + '%'?

2014-04-10 Thread Mark Bird
Hi, thanks but I'm not talking about calling like on a column - I need to 
call like on a string literal. I tried doing text('string').like() but that 
doesn't work either.



On Thursday, 10 April 2014 11:31:23 UTC+1, Gunnlaugur Briem wrote:

 Hi,

 See ColumnElement docs:


 http://docs.sqlalchemy.org/en/rel_0_9/core/sqlelement.html#sqlalchemy.sql.expression.ColumnElement

 ... for your specific example you can call .like(...) on column clauses:

  print Column('foo', Text).like('bar%baz')
 foo LIKE :foo_1

 More generally, if you wanted some operator other than LIKE, existing in 
 your DB dialect but not yet in SQLAlchemy, then you can use .op(...):

  print Column('foo', Text).op('FNORD')('foo%')
 foo FNORD :foo_1

 Cheers,

 Gulli



 On Thu, Apr 10, 2014 at 12:19 PM, Mark Bird mark@gmail.comjavascript:
  wrote:

 I can't seem to find a way to do this without passing raw SQL to .filter()

 I could just do:

 .filter(column == func.substring('string', 1, func.char_length(column)))

 but is it possible to do it with LIKE?

 I.e. I need to return all rows that match the beginning of a string, so 
 for 'string' I could match 's', 'st', 'str', etc.

 Thanks,

 Mark.


  -- 
 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+...@googlegroups.com javascript:.
 To post to this group, send email to sqlal...@googlegroups.comjavascript:
 .
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/d/optout.




-- 
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.


Re: [sqlalchemy] Is it possible to create a filter 'string' LIKE column + '%'?

2014-04-10 Thread Mark Bird
I'm sorry, forget my last response, I see what you mean now.

Thanks a lot!

On Thursday, 10 April 2014 11:31:23 UTC+1, Gunnlaugur Briem wrote:

 Hi,

 See ColumnElement docs:


 http://docs.sqlalchemy.org/en/rel_0_9/core/sqlelement.html#sqlalchemy.sql.expression.ColumnElement

 ... for your specific example you can call .like(...) on column clauses:

  print Column('foo', Text).like('bar%baz')
 foo LIKE :foo_1

 More generally, if you wanted some operator other than LIKE, existing in 
 your DB dialect but not yet in SQLAlchemy, then you can use .op(...):

  print Column('foo', Text).op('FNORD')('foo%')
 foo FNORD :foo_1

 Cheers,

 Gulli



 On Thu, Apr 10, 2014 at 12:19 PM, Mark Bird mark@gmail.comjavascript:
  wrote:

 I can't seem to find a way to do this without passing raw SQL to .filter()

 I could just do:

 .filter(column == func.substring('string', 1, func.char_length(column)))

 but is it possible to do it with LIKE?

 I.e. I need to return all rows that match the beginning of a string, so 
 for 'string' I could match 's', 'st', 'str', etc.

 Thanks,

 Mark.


  -- 
 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+...@googlegroups.com javascript:.
 To post to this group, send email to sqlal...@googlegroups.comjavascript:
 .
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/d/optout.




-- 
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.


Re: [sqlalchemy] Is it possible to create a filter 'string' LIKE column + '%'?

2014-04-10 Thread Mark Bird
That's perfect. Thanks!

On Thursday, 10 April 2014 11:38:24 UTC+1, Simon King wrote:

 You can also use sqlalchemy.literal, which returns an object that you 
 can treat like a column: 

   sqlalchemy.literal('string').like('whatever') 

 You may also be interested in the 'startswith' shortcut, which calls 
 .like under the hood 

   sqlalchemy.literal('string').startswith(yourcolumn) 

 Simon 

 On Thu, Apr 10, 2014 at 11:35 AM, Mark Bird mark@gmail.comjavascript: 
 wrote: 
  I'm sorry, forget my last response, I see what you mean now. 
  
  Thanks a lot! 
  
  
  On Thursday, 10 April 2014 11:31:23 UTC+1, Gunnlaugur Briem wrote: 
  
  Hi, 
  
  See ColumnElement docs: 
  
  
  
 http://docs.sqlalchemy.org/en/rel_0_9/core/sqlelement.html#sqlalchemy.sql.expression.ColumnElement
  
  
  ... for your specific example you can call .like(...) on column 
 clauses: 
  
   print Column('foo', Text).like('bar%baz') 
  foo LIKE :foo_1 
  
  More generally, if you wanted some operator other than LIKE, existing 
 in 
  your DB dialect but not yet in SQLAlchemy, then you can use .op(...): 
  
   print Column('foo', Text).op('FNORD')('foo%') 
  foo FNORD :foo_1 
  
  Cheers, 
  
  Gulli 
  
  
  
  On Thu, Apr 10, 2014 at 12:19 PM, Mark Bird mark@gmail.com 
 wrote: 
  
  I can't seem to find a way to do this without passing raw SQL to 
  .filter() 
  
  I could just do: 
  
  .filter(column == func.substring('string', 1, 
 func.char_length(column))) 
  
  but is it possible to do it with LIKE? 
  
  I.e. I need to return all rows that match the beginning of a string, 
 so 
  for 'string' I could match 's', 'st', 'str', etc. 
  
  Thanks, 
  
  Mark. 
  
  
  -- 
  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+...@googlegroups.com. 
  To post to this group, send email to sqlal...@googlegroups.com. 
  
  Visit this group at http://groups.google.com/group/sqlalchemy. 
  For more options, visit https://groups.google.com/d/optout. 
  
  
  -- 
  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+...@googlegroups.com javascript:. 
  To post to this group, send email to 
  sqlal...@googlegroups.comjavascript:. 

  Visit this group at http://groups.google.com/group/sqlalchemy. 
  For more options, visit https://groups.google.com/d/optout. 


-- 
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] Using flask-sqlalchemy BaseQuery and Pagination with multiple tables.

2014-01-08 Thread Mark S
Hi 

I can successfully use pagination with the following - 

mydata=Article.query.filter(Article.author_id==User.id).filter(User.id==g.user.id).paginate(page,
 
POSTS_PER_PAGE, False)

However, I need to fetch columns from multiple tables. In that case how can 
I modify the code above in order to use pagination? 

Here is what I need to do - 

mydata = db.session.query(id,title,Author).from_statement(\
 SELECT 
a.id,a.title,u.author \
 FROM article a, user u\
 where a.user_id=u.id \
 and u.id=:userid)\

 .params(userid=g.user.id).all()

However, with this , pagination does not work and I get an error 
- AttributeError: 'Query' object has no attribute 'paginate'


Can you please help?




-- 
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/groups/opt_out.


[sqlalchemy] Possible bug with Postgres and ILIKE operator?

2014-01-03 Thread Mark Bird
I am using SQLAlchemy 0.8.1 with a Postgres backend, and have noticed that 
the ilike operator does not seem to be compiling to an ILIKE operator in 
raw SQL, but instead it is doing lower() on both sides of the comparison:

E.g. (names changed to protect the innocent)

 s = session()

 print s.connection().engine
Engine(postgresql://user:passwd@server:port/database)

 q = s.query(Table).filter(Table.column.ilike(FISH%))

 print q
SELECT column
FROM table
WHERE lower(column) LIKE lower(:column_1)

This could be a bug with what is printing out the SQL? I looked at the 
source code and the Postgres dialect is supposed to use ILIKE here. Any 
idea why this is not happening?

-- 
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/groups/opt_out.


Re: [sqlalchemy] Possible bug with Postgres and ILIKE operator?

2014-01-03 Thread Mark Bird
Thanks, that's brilliant. Very much obliged for the fast response. I can
now resolve an issue as nothing to be done, which is always nice :)


On 3 January 2014 18:00, Michael Bayer mike...@zzzcomputing.com wrote:


 On Jan 3, 2014, at 11:53 AM, Mark Bird mark.a.b...@gmail.com wrote:

 I am using SQLAlchemy 0.8.1 with a Postgres backend, and have noticed that
 the ilike operator does not seem to be compiling to an ILIKE operator in
 raw SQL, but instead it is doing lower() on both sides of the comparison:

 E.g. (names changed to protect the innocent)

  s = session()

  print s.connection().engine
 Engine(postgresql://user:passwd@server:port/database)

  q = s.query(Table).filter(Table.column.ilike(FISH%))

  print q
 SELECT column
 FROM table
 WHERE lower(column) LIKE lower(:column_1)

 This could be a bug with what is printing out the SQL? I looked at the
 source code and the Postgres dialect is supposed to use ILIKE here. Any
 idea why this is not happening?


 the select() construct produced by the Query is not bound to the engine’s
 session, so it has no dialect and thus calling str() will use the
 DefaultDialect.  Compiling it with the Postgresql dialect produces the
 desired result, which is the same as that which would occur if you executed
 the statement against the postgresql-bound engine.

  from sqlalchemy import create_engine
  from sqlalchemy import Table, Column, MetaData, String
  t1 = Table('t1', MetaData(), Column('data', String))
  engine = create_engine(postgresql://scott:tiger@localhost/test,
 echo=True)
  from sqlalchemy.orm import Session
  q = Session().query(t1).filter(t1.c.data.ilike('HELLO%'))
  print q
 SELECT t1.data AS t1_data
 FROM t1
 WHERE lower(t1.data) LIKE lower(:data_1)
  print q.statement.compile(engine)
 SELECT t1.data
 FROM t1
 WHERE t1.data ILIKE %(data_1)s







 --
 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/groups/opt_out.




-- 
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/groups/opt_out.


[sqlalchemy] Is it possible to obtain actual values inserted into database in a SessionExtension?

2013-11-13 Thread Mark Bird
I am trying to write a generic auditing extension, but I have some 
inconsistencies I'd like to iron out if possible.

The problem I have is that when an object is updated via a relationship 
rather than a Column attribute, the value returned from 
attributes.get_history is a SQLAlchemy object, and not the value that is in 
the database. This is more pronounced on a many-to-many relationship - the 
secondary table isn't marked as new/dirty, even though that is the table 
that will actually have data inserted into it. Instead the 2 tables joined 
by the secondary table are marked as dirty, although no data is changed in 
those tables. I understand this makes sense at the SQLAlchemy level - but 
is there a way to get the actual database changes? 

A code example to illustrate this:

from sqlalchemy.types import Integer
from sqlalchemy import Column, ForeignKey, create_engine
from sqlalchemy.orm import relationship, backref, attributes, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.interfaces import SessionExtension

BASE = declarative_base()

ENGINE = create_engine(sqlite://)

class AuditListener(SessionExtension):
def after_flush(self, session, *args):
for attr in (new, dirty, deleted):
print attr
for obj in getattr(session, attr):
print %s % obj.__class__.__name__
for col in obj.__mapper__.iterate_properties:
added, unchanged, deleted = attributes.get_history(obj, 
col.key)
if added:
print %s: %s % (col.key, str(added))

SESSION = sessionmaker(
bind=ENGINE,
extension=(AuditListener())
)

class FooBar(BASE):
__tablename__ = 'foobar'
foo_id = Column('foo_id',
ForeignKey('foo.foo_id'),
primary_key=True)

bar_id = Column('bar_id',
ForeignKey('bar.bar_id'),
primary_key=True)

class Foo(BASE):
__tablename__ = 'foo'
foo_id = Column('foo_id',
Integer,
primary_key=True)

bars = relationship('Bar',
secondary=FooBar.__table__,
backref=backref('foos'))

class Bar(BASE):
__tablename__ = 'bar'
bar_id = Column('bar_id',
Integer,
primary_key=True)


def example():
BASE.metadata.create_all(ENGINE, checkfirst=False)

session = SESSION()
f = Foo(foo_id=1)
b1 = Bar(bar_id=1)
b2 = Bar(bar_id=2)
session.add(f)
session.add(b1)
session.add(b2)
session.commit()

# add relationship between f and b1  b2:
f.bars = [b1, b2]
session.commit()

if __name__ == '__main__':
example()

If you run this code you will see this output:

new
Bar
bar_id: [2]
Foo
foo_id: [1]
Bar
bar_id: [1]
dirty
deleted
new
dirty
Bar
Foo
bars: [__main__.Bar object at 0x27b4910, __main__.Bar object at 
0x277b050]
Bar
deleted

As you can see, the output when the many-to-many relationship is committed 
is to denote an update to the bars relationship of Foo. There is nothing 
indicating there are 2 new FooBar entries created.

Any ideas?

Thanks,

Mark.

-- 
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/groups/opt_out.


Re: [sqlalchemy] update using query - joint table inheritance

2013-08-10 Thread Mark Eastwood
Hi Michael,

Thankyou very much for your reply, which is exactly what I needed. I also 
saw the new ticket that was raised for documentation of this, thankyou 
zzzeek.

Mark

-- 
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/groups/opt_out.




[sqlalchemy] update using query - joint table inheritance

2013-08-09 Thread Mark Eastwood
Hi all,

I am getting some unexpected behaviour when trying to update selected rows 
from a query when using joint table inheritance. Using MySQL, a query that 
is filtered based on items in the parent table, does not honour this filter 
when updating items in the child table (all children are updated, not only 
those matching the filter). It is easier to describe in code than in words. 
The code is attached.

In an attempt to make it easier to run, I did try and make the script use 
sqlite instead of MySQL, however in this case an entirely different error 
resulted. I have therefore included both (MySQL enabled, sqlite disabled by 
default).

Can anyone please tell me if there is something that I am doing wrong? is 
this a bug with sqlalchemy?

Thankyou,

Mark Eastwood

-- 
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/groups/opt_out.
'''
Demonstrate a (bug?) in updating records via a query


I am getting some unexpected behaviour when trying to update selected rows from
a query when using joint table inheritance. Using MySQL, a query that is
filtered based on items in the parent table, does not honour this filter when
updating items in the child table (all children are updated, not only those
matching the filter).

In an attempt to make it easier to run, I did try and make the script use
sqlite instead of MySQL, however in this case an entirely different error
resulted. I have therefore included both (MySQL enabled, sqlite disabled by
default).

With MySQL
--

All records within the Child table get updated. What should happen is just the
one record that matches the query gets updated

With SQLite
---

The query raises an OperationalError

Other Debug Info


I have tried this on two different systems with the same result. There are:

System 1:

Operating system: Windows 7 64 bit
Python version = 3.3.1
SQLAlchemy version = 0.8.0
MySQL version = 5.6.13
- included mysqlconnector from windows installer (v1.0.11)

System 2:

Operating system: Windows 7 32 bit
Python v3.3.1
SQLAlchemy v0.8.2
Mariadb version = 5.5.32
MySQLConnector version = 1.0.11
 
To run this script, MySQL (or Mariadb) needs to be installed and a user by the
name of 'tester' with password 'test_password' needs to have access to the
database 'test'@'localhost'. Of course, you can change these.

'''

from sqlalchemy import *
from sqlalchemy.exc import DatabaseError
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

###
# Uncomment one of the following engines
###

#engine = create_engine('sqlite://')

engine = create_engine('mysql+mysqlconnector://%s:%s@%s:%s/%s' % \
  ('tester', 'test_password', '127.0.0.1', '3306', 'test'))

#--

Base = declarative_base()
Base.metadata.bind = engine
session = sessionmaker(bind=engine)()

class Parent(Base):
__tablename__ = 'parent'

id = Column(INTEGER(), primary_key=True)
name = Column(VARCHAR(255), unique=True)
type = Column(VARCHAR(255))

__mapper_args__ = {'polymorphic_identity': 'Parent',
   'polymorphic_on': type}

class Child(Parent):
__tablename__ = 'child'
__mapper_args__ = {'polymorphic_identity': 'Child'}

id = Column(INTEGER(), ForeignKey(Parent.id), primary_key=True)
value = Column(INTEGER(255))

def __repr__(self):
return '%s %s' % (self.name, self.value)

###
# Start with a clean database
###

# MySQL warns if these tables don't exist, despite using IF EXISTS
# SQLAlchemy interprets these as errors, just ignore
try:
session.execute('DROP TABLE IF EXISTS child, parent;')
except DatabaseError:
pass

###
# Build a simple table
###

Base.metadata.create_all()
session.add_all([Child(name='Steven', value=1), 
 Child(name='Mark', value=2), 
 Child(name='Daniel', value=3)])
session.flush()
print('We have three records in the database')
print(session.query(Child).all())

query = session.query(Child).filter

[sqlalchemy] SQLAlchemy 0.7.9 breaks SQLAlchemy-ORM-Tree flush behavior

2012-10-02 Thread Mark Friedenbach
SQLAlchemy 0.7.9 seems to have broken SQLAlchemy-ORM-tree 
(http://pypi.python.org/pypi/SQLAlchemy-ORM-tree/). Specifically, 
SQLAlchemy-ORM-Tree has a dependency on flush behavior prior to the fix for 
#2566. I'm currently investigating a way to detect (and ignore) the 2nd 
flush.

But more generally I'm wondering what motivated #2566 in the first place? 
It has huge compatibility implications for anyone doing tricky things with 
flush and insert/update/delete events.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/nJU2GFvsATYJ.
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.



Re: [sqlalchemy] SQLAlchemy 0.7.9 breaks SQLAlchemy-ORM-Tree flush behavior

2012-10-02 Thread Mark Friedenbach
Well it's hard to boil it down to a specific test case, as it affects the
underlying assumptions that went into the design of ORM-tree. Here's an
explanation of what I'm doing, and perhaps you can tell me if I'm (ab)using
the API correctly:

The meat of the code is a mapper extension whose insert, update, and delete
hooks execute SQL expressions directly to update the nested-interval tree
parameters. For efficiency I use the SQL expression layer and then manually
update the working set of ORM objects to reflect the new state.

In essence:

connection.execute(...update in sql expression language...)
for obj in session.identity_map:
...same update, as python...

(The session.identity_map is accessible to the mapper extension because it
was tucked away as a hidden attribute in the object in a session extension
before_flush handler.)

As far as I can tell, the update to the session objects is now triggering a
2nd flush, even though the purpose of the update was to refresh the objects
with their current database values. On the 2nd flush the SQL expression
updates get executed again, resulting in a corrupt database.

Any red flags in what I'm doing?


All the relevant code is in this file:

https://github.com/monetizeio/sqlalchemy-orm-tree/blob/master/sqlalchemy_tree/orm.py


On Tue, Oct 2, 2012 at 12:07 PM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Oct 2, 2012, at 2:14 PM, Mark Friedenbach wrote:

 SQLAlchemy 0.7.9 seems to have broken SQLAlchemy-ORM-tree (
 http://pypi.python.org/pypi/SQLAlchemy-ORM-tree/). Specifically,
 SQLAlchemy-ORM-Tree has a dependency on flush behavior prior to the fix for
 #2566. I'm currently investigating a way to detect (and ignore) the 2nd
 flush.

 But more generally I'm wondering what motivated #2566 in the first place?
 It has huge compatibility implications for anyone doing tricky things with
 flush and insert/update/delete events.


 #2566 was a serious issue.  If dirty state remains in the session after a
 flush(), then calling commit() had the effect that *two COMMITs are
 emitted*, meaning, one COMMIT, then a brand new transaction, then another
 one, and then any dirty state left by that second commit would just be
 garbage.   The commit() call flushes all remaining dirty state and it is
 essential that the session is clean after a commit occurs.2566's fix
 should only effect when commit() is called.

 Feel free to send me a test case showing a valid usage that is broken by
 this change.


  --
 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.


-- 
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.



Re: [sqlalchemy] SQLAlchemy 0.7.9 breaks SQLAlchemy-ORM-Tree flush behavior

2012-10-02 Thread Mark Friedenbach
I forgot to mention, this is picked up by SQLAlchemy-ORM-tree's unit tests,
if you want to see the failure:

git clone git://github.com/monetizeio/sqlalchemy-orm-tree.git
cd sqlalchemy-orm-tree  make check

On Tue, Oct 2, 2012 at 12:49 PM, Mark Friedenbach m...@monetize.io wrote:

 Well it's hard to boil it down to a specific test case, as it affects the
 underlying assumptions that went into the design of ORM-tree. Here's an
 explanation of what I'm doing, and perhaps you can tell me if I'm (ab)using
 the API correctly:

 The meat of the code is a mapper extension whose insert, update, and
 delete hooks execute SQL expressions directly to update the nested-interval
 tree parameters. For efficiency I use the SQL expression layer and then
 manually update the working set of ORM objects to reflect the new state.

 In essence:

 connection.execute(...update in sql expression language...)
 for obj in session.identity_map:
 ...same update, as python...

 (The session.identity_map is accessible to the mapper extension because it
 was tucked away as a hidden attribute in the object in a session extension
 before_flush handler.)

 As far as I can tell, the update to the session objects is now triggering
 a 2nd flush, even though the purpose of the update was to refresh the
 objects with their current database values. On the 2nd flush the SQL
 expression updates get executed again, resulting in a corrupt database.

 Any red flags in what I'm doing?


 All the relevant code is in this file:


 https://github.com/monetizeio/sqlalchemy-orm-tree/blob/master/sqlalchemy_tree/orm.py



 On Tue, Oct 2, 2012 at 12:07 PM, Michael Bayer 
 mike...@zzzcomputing.comwrote:


 On Oct 2, 2012, at 2:14 PM, Mark Friedenbach wrote:

 SQLAlchemy 0.7.9 seems to have broken SQLAlchemy-ORM-tree (
 http://pypi.python.org/pypi/SQLAlchemy-ORM-tree/). Specifically,
 SQLAlchemy-ORM-Tree has a dependency on flush behavior prior to the fix for
 #2566. I'm currently investigating a way to detect (and ignore) the 2nd
 flush.

 But more generally I'm wondering what motivated #2566 in the first place?
 It has huge compatibility implications for anyone doing tricky things with
 flush and insert/update/delete events.


 #2566 was a serious issue.  If dirty state remains in the session after a
 flush(), then calling commit() had the effect that *two COMMITs are
 emitted*, meaning, one COMMIT, then a brand new transaction, then another
 one, and then any dirty state left by that second commit would just be
 garbage.   The commit() call flushes all remaining dirty state and it is
 essential that the session is clean after a commit occurs.2566's fix
 should only effect when commit() is called.

 Feel free to send me a test case showing a valid usage that is broken by
 this change.


  --
 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.




-- 
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.



Re: [sqlalchemy] SQLAlchemy 0.7.9 breaks SQLAlchemy-ORM-Tree flush behavior

2012-10-02 Thread Mark Friedenbach
Indeed, session.dirty is non-empty within after_flush_postexec().

I'm working on a fix for sqlalchemy-orm-tree first before I can think about
doing a (smaller) regression test. Besides, it now occurs to me that in
some cases I might be setting attributes on objects in the session but
outside of the flush plan (child nodes of a parent that gets moved around,
for example). That could legitimately cause an undesired 2nd
flush. `set_committed_value` looks like what I want to fix that.

On Tue, Oct 2, 2012 at 1:08 PM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Oct 2, 2012, at 4:05 PM, Michael Bayer wrote:

 In theory it would be only .new and .dirty that might have state
 after the flush completes.

 correction, .new and .deleted lists that might have any state.


 --
 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.



-- 
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.



Re: [sqlalchemy] SQLAlchemy 0.7.9 breaks SQLAlchemy-ORM-Tree flush behavior

2012-10-02 Thread Mark Friedenbach
I'm not 100% sure that's what was going on (it was hard to get a debug
shell open at the moment of the error, as opposed to the assertion much
later), but switching those setattr() calls to set_committed_value()
certainly fixed it.

I admit I don't understand the session internals well enough to grok what
you're saying about resetting session.dirty or it being a deeper bug I've
uncovered. If I can be of any assistance with that please let me know.
Regardless, for this project it is no longer an issue as objects are no
longer getting dirtied by setattr() calls in the mapper extension.

Thanks for your help in pointing me down the right track; I'm pushing out a
new version of SQLAlchemy-ORM-tree momentarily.

Cheers,
Mark

On Tue, Oct 2, 2012 at 1:38 PM, Michael Bayer mike...@zzzcomputing.comwrote:

 oh, I know what you're doing, you're modifying the attributes of objects
 that aren't even involved - so yes, the flush normally doesn't go finding
 those, and set_committed_value() would be your workaround for now.

 However, I can modify flush to do this reset for everything that's in
 dirty, rather than just what it knows to have changed.I'd have to
 think about this as I'm not sure it's appropriate.



 On Oct 2, 2012, at 4:28 PM, Mark Friedenbach wrote:

 Indeed, session.dirty is non-empty within after_flush_postexec().

 I'm working on a fix for sqlalchemy-orm-tree first before I can think
 about doing a (smaller) regression test. Besides, it now occurs to me that
 in some cases I might be setting attributes on objects in the session but
 outside of the flush plan (child nodes of a parent that gets moved around,
 for example). That could legitimately cause an undesired 2nd
 flush. `set_committed_value` looks like what I want to fix that.

 On Tue, Oct 2, 2012 at 1:08 PM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Oct 2, 2012, at 4:05 PM, Michael Bayer wrote:

 In theory it would be only .new and .dirty that might have state
 after the flush completes.

 correction, .new and .deleted lists that might have any state.


 --
 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.



 --
 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.


  --
 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.


-- 
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] Introducing SQLAlchemy-ORM-tree: a generic API for hierarchical data

2012-02-28 Thread Mark Friedenbach
I'd like to introduce a package I've been working on for a little
while now: SQLAlchemy-ORM-tree, “an implementation for SQLAlchemy-
based applications of the nested-sets/modified-pre-order-tree-
traversal technique for storing hierarchical data in a relational
database.” It's gone through a couple of semi-public releases already,
but now for the first time the API is complete and semi-stable, and I
would like to get some feedback from developers on this list who have
used or would like to use hierarchical data in an RDBMS through
SQLAlchemy. Some example code to show it in action:


from sqlalchemy_tree import TreeManager
node_table = Table('node', metadata,
  Column('id', Integer, primary_key=True),
  Column('parent_id', Integer, ForeignKey('node.id')))
class Node(object):
  tree = TreeManager(node_table)
mapper(Node, node_table, properties={
  'parent': relationship(Node,
backref = backref('children'),
remote_side = node_table.c.id),
})
Node.tree.register()

root = Node()
session.add(root)
session.flush()
child = Node()
child.parent = root
session.commit()

 child.tree.is_leaf_node
True
 child.tree.query_ancestors().one() == root
True
 child2 = Node()
 Node.tree.insert(child2, root, Node.tree.POSITION_LAST_CHILD)
 session.flush()
 root.tree.query_leaf_nodes() \
 .order_by(Node.tree) \
 .all() == [child, child2]
True
 child2.parent = None
 session.flush()
 child2.tree.is_root_node
True



The PyPI page:

http://pypi.python.org/pypi/SQLAlchemy-ORM-tree

and github (pull requests accepted):

https://github.com/rokusigma/sqlalchemy-orm-tree

Some things to note about the project as it is now: I am operating
under the principles of “1) make it work; 2) make it beautiful; then
finally 3) make it fast”. It works, and to prove it I've written over
300 unit tests in 3.4kLOC covering the expected behavior of all API
entry points. Now I'm soliciting the community's input in making it
“beautiful”--making sure the API is both functional and elegant,
refactoring areas of the code base that need it, making algorithmic
changes, and generally ensuring that the SQLAlchemy-ORM-tree package
is useful to anyone and everyone working with hierarchical data. I'll
then concern myself with low-level modifications for speed.

Some ugly warts I'm aware of (and reasons it's not yet 1.0):

* Making any changes to the structure of the tree requires flushing
before the various tree properties are updated (tree_id, left, right,
depth, etc.), as these updates are handled by a mapper before_flush
event handler and session (before/after)_(insert/update/delete) event
handlers. More subtlety, the introspective APIs `is_leaf_node`,
`is_descendant_of()`, etc. may possibly return incorrect results until
the session is flushed as they rely upon these tree property values.
I'm considering having `insert()` make changes to the database
directly and immediately without waiting for a flush event.

* There are no bulk insert, update, or delete operations. Within the
mapper event handlers each update, insert, and delete is handled in
turn, with all session objects updated accordingly at each stage. I
could use some input as to how best to structure a bulk-load/bulk-
update API from the user's perspective, as I lack experience in this
area.

* The tree manager needs access to the table at initialization time...
which in the declarative style means that the tree manager has to be
monkey-patched into the class object after it is defined. Suggestions
for improving this would be appreciated.

* The API for both inserting nodes AND updating the location of
existing nodes is `insert()`, the analogy being inserting into a
specific position in a list. It's confusing however as one uses it for
updates as well as insertions, and it also has nothing to do with the
SQL INSERT statement. `update()` or `move()` wouldn't be any better
for the same or similar reasons. Nomenclature suggestions would be
much appreciated.

* I just today learned about Tropashko's nested interval tree encoding
using continued fractions. I admit that I don't (yet) fully understand
the underlying maths, but appears that switching to continued
fractions over integers for the left/right fields could lead to
significant algorithmic gains in performance. Thankfully this could be
a transparent switch with no external API changes.

Happy hacking,
Mark

-- 
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] Set-based association proxy through AppenderQuery?

2012-02-11 Thread Mark Friedenbach
Hi,

Is it possible to have an association_proxy (in the association object
pattern) that emulates a set-based collection if it goes through a
lazy='dynamic' relationship? I can't for the life of me find a way to
make this work (setting collection_class on the dynamic relationship
doesn't seem to do anything).

Here's some example code of what I'm trying to do, extracted from the
actual project:

class ProofOfWork(object):
  blocks = association_proxy('Intermediatory_nodes', 'block')
proof_of_work = Table('proof_of_work', db.metadata)
mapper(ProofOfWork, proof_of_work, properties={
  'Intermediatory_nodes': relationship(lambda: Intermediatory,
lazy = 'dynamic'),
})

class Block(object):
  proof_of_works = association_proxy('Intermediatory_nodes',
'proof_of_work')
block = Table('block', db.metadata)
mapper(Block, block, properties={
  'Intermediatory_nodes': relationship(lambda: Intermediatory,
lazy = 'dynamic'),
})

class Intermediatory(object):
  pass
intermediatory = Table('intermediatory', db.metadata,
  Column('proof_of_work_id', Integer,
ForeignKey('proof_of_work.id'),
nullable = False),
  Column('block_id', Integer,
ForeignKey('block.id')),
)
mapper(Intermediatory, intermediatory, properties={
  'proof_of_work': relationship(lambda: ProofOfWork,
back_populates = 'Intermediatory_nodes',
remote_side= lambda: proof_of_work.c.id),
  'block': relationship(lambda: Block,
back_populates = 'Intermediatory_nodes',
remote_side= lambda: block.c.id),
})

How can I make ProofOfWork.blocks and Block.proof_of_works return an
_AssociationSet instead of _AssociationList?

Cheers,
Mark

-- 
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: Expiring only unchanged stale data

2012-02-05 Thread Mark Friedenbach
Thanks Michael, the 'solution' is seems was to refactor my code so
that operations are clearly performed in the correct order, and in
some cases to explicitly load and/or update the tree parameters when
they might have changed. Now I'm not only doing before_flush (which
I've restricted to session/ORM queries only), but also before/after
insert, update, and delete (where I only do SQL expression queries).

On Feb 4, 8:52 am, Michael Bayer mike...@zzzcomputing.com wrote:
 On Feb 4, 2012, at 11:23 AM, Mark Friedenbach wrote:
  Hi, I'm running into a problem with my nested sets implementation.
  Inserting, moving, or removing a node can potentially affect one or
  more of many other nodes' tree properties (tree id, left, right,
  depth, or parent relationship). For efficiency's sake this change
  occurs as a single, rather complex SQL expression query that handles
  the magic of updating all the other node values.

  Just as a precaution I've added a session.expire_all() after the
  session.execute(query), so that the tree values will be reloaded as
  I move on to process other node operations in the same transaction.
  However what I've discovered is that expire_all() causes *all* as-of-
  yet unpersisted changes to be lost. As an example of what I mean,
  here's an actual shell log:

  obj = session.query(...)
  obj.name
  u'root1'
  obj.name = 'root66'
  session.add(obj)
  session.expire_all()
  session.commit()
  obj.name
  u'root1'

  It may be possible that I can restructure the order in which I do
  things so that stale data isn't an issue. But out of curiosity, is
  there a way to expire only *unchanged* stale data? This is how I
  naïvely expected expire_all() to work.

 all means everything, that method is called typically after rollback() or 
 commit() in conjunction with the transaction.

 While there is a way to detect history on all attributes and expire just 
 those with no net change, this is a time consuming operation and should not 
 be necessary.

 In this case, you know that the only values that are being updated outside of 
 the normal flush process are the left and right columns (and whatever 
 denormalized data you're storing such as depth), so you should just be 
 expiring those, and it should be either within the after_flush event:

 http://docs.sqlalchemy.org/en/latest/orm/events.html?highlight=after%...

 These attributes will refresh themselves when next accessed.

 Or if you have a means available of populating some of these attributes with 
 their correct value instead of just expiring, you can use 
 attributes.set_committed_value():

 http://docs.sqlalchemy.org/en/latest/orm/session.html?highlight=set_c...

 Reading your paragraph again, if you're actually doing the math for 
 left/right/depth in Python and need the value of those attributes to be 
 correct as the flush() proceeds, I'd consider doing the math in SQL, as you 
 can't assume all the nodes are going to be loaded into memory.

  Alternatively, a good API for this case would have been an
  expire_all(mapped_class, ['attribute', 'names']), a sort of compromise
  between expire() and expire_all().

 You can roll this yourself:

 for obj in session.identity_map.values():
     if isinstance(obj, myclass):
         session.expire(obj, ['a', 'b'])









  --
  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 
  athttp://groups.google.com/group/sqlalchemy?hl=en.

-- 
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] Expiring only unchanged stale data

2012-02-04 Thread Mark Friedenbach
Hi, I'm running into a problem with my nested sets implementation.
Inserting, moving, or removing a node can potentially affect one or
more of many other nodes' tree properties (tree id, left, right,
depth, or parent relationship). For efficiency's sake this change
occurs as a single, rather complex SQL expression query that handles
the magic of updating all the other node values.

Just as a precaution I've added a session.expire_all() after the
session.execute(query), so that the tree values will be reloaded as
I move on to process other node operations in the same transaction.
However what I've discovered is that expire_all() causes *all* as-of-
yet unpersisted changes to be lost. As an example of what I mean,
here's an actual shell log:

 obj = session.query(...)
 obj.name
u'root1'
 obj.name = 'root66'
 session.add(obj)
 session.expire_all()
 session.commit()
 obj.name
u'root1'

It may be possible that I can restructure the order in which I do
things so that stale data isn't an issue. But out of curiosity, is
there a way to expire only *unchanged* stale data? This is how I
naïvely expected expire_all() to work.

Alternatively, a good API for this case would have been an
expire_all(mapped_class, ['attribute', 'names']), a sort of compromise
between expire() and expire_all().

-- 
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.



Re: [sqlalchemy] Column Mixin

2011-11-27 Thread Mark Erbaugh

 Am 26.11.2011 15:26 schrieb Mark Erbaugh m...@microenh.com:
 
 I'm using a ColumnMixin to have a subset of columns common in two tables.  Is 
 there an easy way to populate the common columns in one descendent table with 
 the corresponding columns in a row of the other descendent tables, and can 
 this be a method of the ColumnMixin class?  Ideally, I'd like the copy method 
 to dynamically respond to changes in the ColumnMixin class (i.e. if I add a 
 column defiinition to the mixin, I don't want to have to modify the copy 
 method).
 
 Thanks,
 Mark

On Nov 27, 2011, at 4:06 AM, Robert Forkel wrote:

 Hi,
 I'm doing something similar and ended up giving all columns contributed by a 
 mixin a common prefix, and have the copy method loop over all columns of an 
 object, picking out the right ones.
 Regards
 Robert
 

Robert,

Thanks for the reply. I ended up with a different approach, illustrated by the 
code snippet:

_sizing_pump_columns = (
('pump', String(6)),
('mod_date', String(19)),
('curve', String(15)),
('eq_gpm', Float),
('eq_psi', Float),
)

current_pump_table = Table('current_pump', Base.metadata,
Column('id', Integer, primary_key=True),
Column('user', String, ForeignKey('user._user')),
*[Column(*i) for i in _sizing_pump_columns]
)

pump_table = Table('pump', Base.metadata,
Column('id', Integer, primary_key=True),
Column('sizing_id', Integer, ForeignKey('sizing.id')),
*[Column(*i) for i in _sizing_pump_columns]
)

class _SizedPumpBase(object):
def copy(self, other):
 
copy data from other into self

for i in _sizing_pump_columns:
self.__dict__[i[0]] = other.__dict[i[0]]


class SizedPump(_SizedPumpBase):
pass

class SizedPumpCurrent(_SizedPumpBase):
pass

mapper(SizedPumpCurrent, current_pump_table)
mapper(SizedPump, pump_table)

I switched from SA declarative to the separate table and mapper, so I could use 
the _sizing_pump_columns tuple for the definition of the current_pump_table and 
pump_table objects and use field names in the copy method.  As of now, it's 
passing my unit tests, but I'd appreciate any comments specifically on 
something I might have missed.

Mark

-- 
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] Column Mixin

2011-11-26 Thread Mark Erbaugh
I'm using a ColumnMixin to have a subset of columns common in two tables.  Is 
there an easy way to populate the common columns in one descendent table with 
the corresponding columns in a row of the other descendent tables, and can this 
be a method of the ColumnMixin class?  Ideally, I'd like the copy method to 
dynamically respond to changes in the ColumnMixin class (i.e. if I add a column 
defiinition to the mixin, I don't want to have to modify the copy method).

Thanks,
Mark

-- 
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] Dynamic data member instrumentation with declarative

2011-11-10 Thread Mark Erbaugh
I'm trying to use data from a sequence to add columns to a SQLAlchemy table 
created declaratively. Here's what I'm doing:

class Sizing(Base):
__tablename__ = 'sizing'
id = Column(Integer, primary_key=True)

[...]


for name in ('column1', 'column2', 'column3', ...):
x = Column(type_=Integer)
x.name = name
Sizing.__table__.append_column(x)

This works as far as creating the table in the database, i.e. viewing the 
database shows columns named column1, column2, column3, etc, but code like 
getattr(sizing, 'column1')  (sizing is an instance of Sizing) is failinging 
with a message 'Sizing' object has no attribute 'column1'

While code like:

Sizing.colum1 = Column(Integer)

works, but

Sizing.__dict__['column1'] = Column(Integer)
or

Sizing.__setattr__(Sizing, 'column1', Column(Integer))

fails

The reason I'm trying to use the sequence to create the colums is that data 
from the sequence containing the column names is used in other parts of the 
application and I'd like to maintain that data in just one place. It's okay if 
I have to rebuild the database when the columns in the sequence change.

Thanks,
Mark

-- 
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.



Re: [sqlalchemy] Dynamic data member instrumentation with declarative

2011-11-10 Thread Mark Erbaugh

On Nov 10, 2011, at 12:57 PM, Michael Bayer wrote:

 
 On Nov 10, 2011, at 9:34 AM, Mark Erbaugh wrote:
 
 I'm trying to use data from a sequence to add columns to a SQLAlchemy table 
 created declaratively. Here's what I'm doing:
 
 class Sizing(Base):
   __tablename__ = 'sizing'
   id = Column(Integer, primary_key=True)
 
   [...]
 
 
 for name in ('column1', 'column2', 'column3', ...):
   x = Column(type_=Integer)
   x.name = name
   Sizing.__table__.append_column(x)
 
 
 that will just add the column to the table but won't map it.   the mapper 
 isn't aware of this operation.
 
 
 This works as far as creating the table in the database, i.e. viewing the 
 database shows columns named column1, column2, column3, etc, but code like 
 getattr(sizing, 'column1')  (sizing is an instance of Sizing) is failinging 
 with a message 'Sizing' object has no attribute 'column1'
 
 While code like:
 
 Sizing.colum1 = Column(Integer)
 
 works, but
 
 right so that hits the __setattr__ of the DeclarativeMeta class which 
 receives the Column object, checks it out, and assigns it correctly to the 
 mapper and table.
 
 
 Sizing.__dict__['column1'] = Column(Integer)
 
 In general, you should never set attributes this way from the outside, that's 
 just a Python thing, as you're bypassing whatever attribute set mechanics may 
 be present on the target object.
 
 or
 
 Sizing.__setattr__(Sizing, 'column1', Column(Integer))
 
 this is not much different as again you're bypassing instrumentation that may 
 be available on the class.   Use the Python setattr() function instead:  
 setattr(Sizing, name, object).


Thanks so much!

Mark

-- 
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.



Re: [sqlalchemy] select count(*)

2011-11-04 Thread Mark Erbaugh

On Nov 4, 2011, at 4:54 AM, Stefano Fontanelli wrote:

 Il 04/11/11 03.08, Mark Erbaugh ha scritto:
 
 On Nov 3, 2011, at 2:54 PM, Stefano Fontanelli wrote:
 
 Il 03/11/11 19.18, Mark Erbaugh ha scritto:
 Using the query object count() method generates a sub-query (as per the 
 docs). The docs say to use func.count to avoid the subquery. func.count 
 seems to require a field object. Is there a way to generate a query that 
 essentially becomes 'select count(*) from table' using the ORM, not the 
 SQL generator?
 
 Thanks,
 Mark
 
 Did you try func.count('*')?
 How would you specify the table you want counted?  I trued 
 func.count('table.*') and that didn't work.
 
 Check the manual: http://www.sqlalchemy.org/docs/orm/tutorial.html#counting
 
 To achieve our simple SELECT count(*) FROM table, we can apply it as:
 
 SQL session.query(func.count('*')).select_from(User).scal
 ar()
 
 Is that right for you?

Stefano,

Thanks. I missed that in the documentation and it does indeed generate the 
expected SQL (at least with SQLite).

Mark

-- 
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] select count(*)

2011-11-03 Thread Mark Erbaugh
Using the query object count() method generates a sub-query (as per the docs). 
The docs say to use func.count to avoid the subquery. func.count seems to 
require a field object. Is there a way to generate a query that essentially 
becomes 'select count(*) from table' using the ORM, not the SQL generator?

Thanks,
Mark

-- 
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.



Re: [sqlalchemy] select count(*)

2011-11-03 Thread Mark Erbaugh

On Nov 3, 2011, at 2:54 PM, Stefano Fontanelli wrote:

 Il 03/11/11 19.18, Mark Erbaugh ha scritto:
 Using the query object count() method generates a sub-query (as per the 
 docs). The docs say to use func.count to avoid the subquery. func.count 
 seems to require a field object. Is there a way to generate a query that 
 essentially becomes 'select count(*) from table' using the ORM, not the SQL 
 generator?
 
 Thanks,
 Mark
 
 Did you try func.count('*')?

How would you specify the table you want counted?  I trued 
func.count('table.*') and that didn't work.

Mark

-- 
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.



Re: [sqlalchemy] select count(*)

2011-11-03 Thread Mark Erbaugh

On Nov 3, 2011, at 3:31 PM, werner wrote:

 Mark,
 
 On 11/03/2011 07:18 PM, Mark Erbaugh wrote:
 Using the query object count() method generates a sub-query (as per the 
 docs). The docs say to use func.count to avoid the subquery. func.count 
 seems to require a field object. Is there a way to generate a query that 
 essentially becomes 'select count(*) from table' using the ORM, not the SQL 
 generator?
 Just the other day I thought I needed the same, initially I just used the 
 id column which all my tables had, but as count(anything) is pretty 
 expensive (using Firebird SQL - so might be different for other dbs) I wanted 
 to find a way without using count().  In my case I needed at some point to 
 get all the id values of that table (to build a virtual listctrl in 
 wxPython), so instead of doing the count and starting feeling the list I got 
 the id and did a len(onresult) to get my count.
 
 Point I am trying to make with a lot of words, maybe there is a solution 
 which doesn't need count() at all:-) .

I never considered that a count(*) was that expensive especially if there is no 
where clause. I would think that it would be less expensive than actually 
retrieving all the rows and counting them.  What if there are millions of rows? 
The result set could fill up memory. In my case, I just need to know how many 
rows. I don't care about any other details. In one case, I'm checking to see if 
there are zero rows, in which case, I populate the table with initial rows. In 
another case, I'm just unittesting some code and I want to make sure that there 
are the proper number of rows in the table as one of the test conditions.

Mark

-- 
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] count rows in a table

2011-10-25 Thread Mark Erbaugh
What's the recommended way to count the rows in a table. In SQL,  I would 
typically use select count(*) from table;

The statement session.query(table).count()  issues a count(*) on a sub-query. 
 The docs say for finer control to use func.count

i.e. session.query(func.count(table.column)). That works, but you do have to 
specify a table column.

session.query(func.count('table.*')) also appears to work, but issues a 
parameterized query.

Is getting the count (however it's done) and checking for 0 the best way to 
check for an empty table?

Mark


-- 
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.



Re: [sqlalchemy] Degenerate relationship?

2011-10-15 Thread Mark Erbaugh

On Oct 15, 2011, at 10:17 AM, Michael Bayer wrote:

 
 On Oct 14, 2011, at 9:45 PM, Mark Erbaugh wrote:
 
 There are two tables pump and curve. The curve table has three fields, 
 curve_pn, head and gpm. The design is that the rows with the same curve_pn 
 value represent x,y points (head,gpm) on a pump performance curve. Each row 
 in the pump table has a curve_pn column that links to the performance curve 
 for that pump. The same performance curve can apply to multiple pumps.
 
 To me it seems that there is a many-many relationship, yet there is no 
 association table.  This design works fine in straight SQL. To model it in 
 SQLAlchemy, do I need to add an association table?  For the purposes of this 
 application, the data is read-only, but if it were not, if the data for a 
 curve were to change, I would want it to change for all the pumps that use 
 that curve_pn.
 
 SQLAlchemy's rules are more relaxed than relational database rules here, 
 which would definitely require that you use proper foreign keys.   In SQLA's 
 case it populates local to remote from A-B as the configuration tells it to, 
 does a join on lookup, and primaryjoin/foreign_keys does what you need:
 

Thanks

-- 
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] Degenerate relationship?

2011-10-14 Thread Mark Erbaugh
There are two tables pump and curve. The curve table has three fields, 
curve_pn, head and gpm. The design is that the rows with the same curve_pn 
value represent x,y points (head,gpm) on a pump performance curve. Each row in 
the pump table has a curve_pn column that links to the performance curve for 
that pump. The same performance curve can apply to multiple pumps.

To me it seems that there is a many-many relationship, yet there is no 
association table.  This design works fine in straight SQL. To model it in 
SQLAlchemy, do I need to add an association table?  For the purposes of this 
application, the data is read-only, but if it were not, if the data for a curve 
were to change, I would want it to change for all the pumps that use that 
curve_pn.

TIA,
Mark

-- 
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] Get value from field class and instance

2011-09-06 Thread Mark Erbaugh
Let's say there is a mapped (declaratively, but that shouldn't matter) class, 
Data, that has fields Data.value1, ... Data.value10.

There is also an instance of this class, data that is populated from the data 
table.

Obviously, you can get the values using data.value1, ...

But is there a simple way to get a data value using the instance object (data) 
and a class field (Data.value1).

What's the easiest way given data and Data.value1 to get / set that value of 
data.value1? 

So far I've come up with:

Data.__getattribute__(data, Data.value1.property.columns[0].name)  but is there 
a more direct way?

==

If you're curious, here's what I'm trying to do.  I have an calculation that 
sums a calculation on all of a particular type of field. If I add a new field 
of this type to the table, it would be nice if it were automatically included 
in the calculation.

I've created a custom descendent of Column for this type of column. When the 
constructor of this custom class is called during the table construction, it 
adds the created field to a list. The calculation should then step through the 
columns in this list when calculating the value.


Thanks,
Mark



-- 
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.



Re: [sqlalchemy] Get value from field class and instance

2011-09-06 Thread Mark Erbaugh

On Sep 6, 2011, at 2:48 PM, Michael Bayer wrote:

 
 On Sep 6, 2011, at 2:38 PM, Mark Erbaugh wrote:
 
 Let's say there is a mapped (declaratively, but that shouldn't matter) 
 class, Data, that has fields Data.value1, ... Data.value10.
 
 There is also an instance of this class, data that is populated from the 
 data table.
 
 Obviously, you can get the values using data.value1, ...
 
 But is there a simple way to get a data value using the instance object 
 (data) and a class field (Data.value1).
 
 What's the easiest way given data and Data.value1 to get / set that value of 
 data.value1? 
 
 Data.value1 is a Python descriptor, so Data.value1.__get__(data, Data) would 
 do it.Or getattr(data, Data.value1.key) as key is present on the SQLA 
 instrumented attribute.
 

Thanks.

-- 
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.



Re: [sqlalchemy] Repetitive Fields in declarative

2011-08-19 Thread Mark Erbaugh

On Aug 18, 2011, at 7:01 PM, Mark Erbaugh wrote:

 
 On Aug 18, 2011, at 6:06 PM, Mark Erbaugh wrote:
 
 want to create a table that has several similar fields. For example, assume 
 the fields are field1, field2, ...
 
 Is there a way in the declarative class that I can do something like:
 
 for i in range(10):
  'field%d' % i = Column( ... )
 
 
 Thanks,
 Mark
 
 
 Figured it out:
 
 after the class definition:
 
 for i in range(10):
   class.__table__.append_column(Column('field%d' % i, ...))


I guess not: while the above code adds the fields to the database table, it 
doesn't add them as named data members of the class.  Here's my latest effort:

class Preferences:
...

for i in range(10):
setattr(Preferences, 'field%d' % i, Column(...

This also answers my question about relationships

setattr(Preferences 'relationship%d' % i, relationship(...


Mark

-- 
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.



Re: [sqlalchemy] Repetitive Fields in declarative

2011-08-19 Thread Mark Erbaugh

On Aug 19, 2011, at 10:41 AM, Michael Bayer wrote:

 Id use a mixin so that a superclass can be generated in a data driven manner:
 
 
 MyCols = type(MyCols, (object, ), dict((field%d % i, Column(Integer)) for 
 i in xrange(1, 10)))
 
 class MyClass(MyCols, Base):
...
 
 otherwise if you want to go the append_column() route, you can just tack them 
 on the class, declarative will call append_column() as well as 
 mapper.add_property():
 
 for name, col in (field%d % i, Column(Integer)) for i in xrange(1, 10)):
setattr(MyClass, name, col)


Michael,

Thanks for the info.

Mark

-- 
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] Handling optional relationship

2011-08-19 Thread Mark Erbaugh
I have a table that has a foreign key field that is optional.  IOW, the current 
row may be linked to at most one row in the foreign table. If the foreign key 
field is not NULL, it must point to a valid row in the foreign table, but if it 
is NULL that means that it it not linked.

Is there an automatic way to have the value of the foreign key field set to 
NULL if the linked row in the foreign table is deleted?

Thanks,
Mark

-- 
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.



Re: [sqlalchemy] Handling optional relationship

2011-08-19 Thread Mark Erbaugh

On Aug 19, 2011, at 2:10 PM, Mike Conley wrote:

 class Parent(Base):
 __tablename__ = 'parent'
 id = Column(Integer, primary_key=True)
 class Child(Base):
 __tablename__ = 'child'
 id = Column(Integer, primary_key=True)
 p_id = Column(Integer, ForeignKey(Parent.id))
 parent = relation(Parent, backref=backref('children', 
 cascade=save-update,merge))
 
 sess.add(Parent(children=[Child(),Child()]))
 sess.commit()
 p = sess.query(Parent).first()
 sess.delete(p)
 sess.commit()


Mike,

Thanks. that does indeed work.  For some reason, it didn't seem to be work in 
my schema.  I'll have to do some more testing.

Mark

-- 
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] Repetitive Fields in declarative

2011-08-18 Thread Mark Erbaugh
I want to create a table that has several similar fields. For example, assume 
the fields are field1, field2, ...

Is there a way in the declarative class that I can do something like:

for i in range(10):
'field%d' % i = Column( ... )


Thanks,
Mark

-- 
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.



Re: [sqlalchemy] Repetitive Fields in declarative

2011-08-18 Thread Mark Erbaugh

On Aug 18, 2011, at 6:06 PM, Mark Erbaugh wrote:

  want to create a table that has several similar fields. For example, assume 
 the fields are field1, field2, ...
 
 Is there a way in the declarative class that I can do something like:
 
 for i in range(10):
   'field%d' % i = Column( ... )
 
 
 Thanks,
 Mark


Figured it out:

after the class definition:

for i in range(10):
class.__table__.append_column(Column('field%d' % i, ...))

Mark

-- 
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.



Re: [sqlalchemy] Repetitive Fields in declarative

2011-08-18 Thread Mark Erbaugh
Me again (see below):

On Aug 18, 2011, at 7:01 PM, Mark Erbaugh wrote:

 
 On Aug 18, 2011, at 6:06 PM, Mark Erbaugh wrote:
 
 want to create a table that has several similar fields. For example, assume 
 the fields are field1, field2, ...
 
 Is there a way in the declarative class that I can do something like:
 
 for i in range(10):
  'field%d' % i = Column( ... )
 
 
 Thanks,
 Mark
 
 
 Figured it out:
 
 after the class definition:
 
 for i in range(10):
   class.__table__.append_column(Column('field%d' % i, ...))

Some of the fields that I am adding this way are foreign keys to another table. 
Is there a way to specify a relationship based on these foreign key fields?

Mark

-- 
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.



Re: [sqlalchemy] Group / Order by field in relationship?

2011-08-17 Thread Mark Erbaugh

On Aug 17, 2011, at 10:15 AM, Conor wrote:

 On 08/17/2011 12:01 AM, Mark Erbaugh wrote:
 
 Is it possible to group or order by a field in a many to one related table?
 
 class Rental(Base):
 __tablename__ = 'rental'
 
 rental_id = Column(Integer, autoincrement=True, primary_key=True)
 inventory_id = Column(Integer, ForeignKey(Inventory.inventory_id), 
 nullable=False)
 
 inventory = relation(Inventory,
 uselist=False,
 backref='rentals',
 )
 
 class Inventory(Base):
 __tablename__ = 'inventory'
 
 inventory_id = Column(Integer, autoincrement=True, primary_key=True)
 film_id = Column(Integer, ForeignKey(Film.film_id), nullable=False)
 
 film = relation(Film,
 uselist=False,
 backref='inventory',
 )
 
 
 
 session.query(Rental).order_by(Rental.inventory.film_id)  generates the 
 error:
 
 Neither 'InstrumentedAttribute' object nor 'Comparator' object has an 
 attribute 'film_id'
 You have to explicitly join to the related table, e.g.:
 
 session.query(Rental).join(Rental.inventory).order_by(Inventory.film_id)
 For bonus points, you can tell SQLAlchemy that Rental.inventory has been 
 eagerloaded. This may reduce the number of lazy loads when you access a 
 Rental instance's inventory:
 
 q = session.query(Rental)
 q = q.join(Rental.inventory)
 q = q.options(sqlalchemy.orm.contains_eager(Rental.inventory))
 q = q.order_by(Inventory.film_id)
 -Conor
 
Conor,

Thanks for the information / confirmation. I had found that the explicit union 
worked, but I know there's a lot of SA that I don't understand and was 
concerned I was missing something.

Mark

-- 
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] Group / Order by field in relationship?

2011-08-16 Thread Mark Erbaugh
Is it possible to group or order by a field in a many to one related table?

 class Rental(Base):
 __tablename__ = 'rental'
 
 rental_id = Column(Integer, autoincrement=True, primary_key=True)
 inventory_id = Column(Integer, ForeignKey(Inventory.inventory_id), 
 nullable=False)
 
 inventory = relation(Inventory,
 uselist=False,
 backref='rentals',
 )

 class Inventory(Base):
 __tablename__ = 'inventory'
 
 inventory_id = Column(Integer, autoincrement=True, primary_key=True)
 film_id = Column(Integer, ForeignKey(Film.film_id), nullable=False)
 
 film = relation(Film,
 uselist=False,
 backref='inventory',
 )



session.query(Rental).order_by(Rental.inventory.film_id)  generates the error:

Neither 'InstrumentedAttribute' object nor 'Comparator' object has an attribute 
'film_id'

Thanks,
Mark

-- 
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.



Re: [sqlalchemy] Softcoding .filter(...)

2011-08-12 Thread Mark Erbaugh

On Aug 12, 2011, at 10:21 AM, RVince wrote:

 I'm trying to discern a means of creating a .filter(A rel B) where the
 values for A, rel and B come from an parameters passed in to the web
 page.
 
 I already have an SQLAlchemy statement, say
 query = Session.query(table).filter(A==B)
 
 and I want to be able to allow for a drilldown of sorts by the, such
 that from the web page they can pick a value from a dropdown, a
 relation (from a dropdown) and a textbox to compare to. But my problem
 is once I have these three values, how do I get them into
 the .filter() function? That's not going to merely accept string
 values -- is there a way to do this?
 
 Thanks, RVince
 

You can build your SQLAlchemy queries dynamically, i.e.

q1 = query.Session.query(table).filter(A == B)

q2 = q1.filter(C == D)

q3 = q2.filter(E == F)

you could apply different relationships using conditional Python statements:

if rel == 'eq':
q4 = q3.filter(G == H)
elif rel == 'neq':
q4 = q3.filter(G != H)

is this what you're looking for?

Mark

-- 
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.



Re: [sqlalchemy] Re: Softcoding .filter(...)

2011-08-12 Thread Mark Erbaugh

On Aug 12, 2011, at 11:52 AM, NiL wrote:

 say you want to filter on the 'field' (field would be a string representing 
 the name of the field) on objects of class == Klass
 
 field_attr = getattr(Klass, field)
 
  would give you the instrumented attribute
 
 then
 
 Session.query(Klass).filter(field_attr == searchString)
 
 or
 
 Session.query(Klass).filter(field_attr.endswith(searchString))
 
 would run
 
 HTH
 
 NiL

You can also use the class's __dict__ member:

field_attr = Klass.__dict__['field']

It really amazes me how Pythonic SQLAlchemy makes database access.

Mark



-- 
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] declarative __table__ columns

2011-08-12 Thread Mark Erbaugh
Is there a way to access the parameters to the Column() call used to set up a 
database table when given either an instance field or class field?

For example:

class MyClass(Base):
...
f1 = Column(Integer, nullable=False, info={'min':0})
...

If I have MyClass.f1 or my_class.f1 (where my_class is an instance of MyClass) 
is there a way to get nullable or info?

The only way I've come up with so far is to match the __table__.columns 
elements on the name parameter.

Thanks,
Mark

-- 
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.



Re: [sqlalchemy] declarative __table__ columns

2011-08-12 Thread Mark Erbaugh

On Aug 12, 2011, at 5:26 PM, Michael Bayer wrote:

 
 Is there a way to access the parameters to the Column() call used to set up 
 a database table when given either an instance field or class field?
 
 For example:
 
 class MyClass(Base):
  ...
  f1 = Column(Integer, nullable=False, info={'min':0})
  ...
 
 If I have MyClass.f1 or my_class.f1 (where my_class is an instance of 
 MyClass) is there a way to get nullable or info?
 
 The only way I've come up with so far is to match the __table__.columns 
 elements on the name parameter.
 
 if you have MyClass.fi, column is MyClass.f1.property.columns[0].


Thanks - just what I was looking for!

Mark

-- 
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.



Re: [sqlalchemy] Default values

2011-08-06 Thread Mark Erbaugh

On Aug 6, 2011, at 7:18 AM, Mike Conley wrote:

 You can get to the column default value.
 
 class MyTable(Base):
 __tablename__ = 'table'
 id = Column(Integer, primary_key=True)
 name = Column(String, default='new name')
 def __init__(self, name=None):
 if name is not None:
 self.name = name
 else:
 self.name = getDefault(self, 'name')
 def getDefault(instance, colName):
 col = instance.__table__.c[colName]
 if col.default is not None:
 dflt = col.default.arg
 else:
 dflt = None
 return dflt


Mike,

Thanks.  I adapted your code:

def __init__(self):
for col in self.__table__.c:
if col.default is not None:
self.__setattr__(col.key, col.default.arg)


Mark

-- 
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] Default values

2011-08-05 Thread Mark Erbaugh
In a declaratively created table, is there an automatic way to get a new 
instance of the class object to be populated with values specified in a 
'default' clause?

i.e.

class MyTable(Base):
__tablename__ = 'table'
name = Column(String, default='new name')
...


newRow = MyTable()

is there a way to have newRow.name automatically have the value 'new name' 
before it is committed to the database?  The best I've been able to come up 
with so far is to use a 'CONSTANT' in the default clause and use that same 
CONSTANT to initialize the field in the class' __init__, but this doesn't seem 
very DRY.

Or, maybe is this the wrong question?  Maybe I'm trying to do things the wrong 
way. I'm trying to use mostly the same code add a new row or edit an existing 
row.  If the user is adding a record, I create a new instance of the class and 
use the add/edit screen to edit the data. If the user is editing an existing 
row, I retrieve the row, then use the add/edit screen with it.

Thanks,
Mark

-- 
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] Declarative Field Type 'Alias'

2011-08-05 Thread Mark Erbaugh
In my application, some tables have several fields that need to have the same 
type and default value, i.e.:

field1 = Column(Integer, default=2)
field2 = Column(Integer, default=2)
...

Is there some way to refactor the Common(Integer, default=2), short of creating 
a custom column type?  I could see the possibility that in a future version of 
the application, I would want to globally change the column type or default 
value for all these fields at once.

So far, I've come up with creating a function that returns the column.

def common_field():
return Column(Integer, default=2)

field1 = common_field()
field2 = common_field()

Is there a better way?

Mark

-- 
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.



Re: [sqlalchemy] Default values

2011-08-05 Thread Mark Erbaugh

On Aug 5, 2011, at 2:00 PM, Stefano Fontanelli wrote:

 Il 05/08/11 19.29, Mark Erbaugh ha scritto:
 In a declaratively created table, is there an automatic way to get a new 
 instance of the class object to be populated with values specified in a 
 'default' clause?
 
 i.e.
 
 class MyTable(Base):
  __tablename__ = 'table'
  name = Column(String, default='new name')
 ...
 
 
 newRow = MyTable()
 
 is there a way to have newRow.name automatically have the value 'new name' 
 before it is committed to the database?  The best I've been able to come up 
 with so far is to use a 'CONSTANT' in the default clause and use that same 
 CONSTANT to initialize the field in the class' __init__, but this doesn't 
 seem very DRY.
 
 Or, maybe is this the wrong question?  Maybe I'm trying to do things the 
 wrong way. I'm trying to use mostly the same code add a new row or edit an 
 existing row.  If the user is adding a record, I create a new instance of 
 the class and use the add/edit screen to edit the data. If the user is 
 editing an existing row, I retrieve the row, then use the add/edit screen 
 with it.
 
 Thanks,
 Mark
 
 
 Hi Mark,
 to fill with defaults you can do:
 
 newRow = MyTable()
 session.add(newRow)
 session.flush()
 print newRow.name
 
 'print newRow.name' will display 'new name'
 
 To use the same code for create/update I suggest you to use session.merge: 
 http://www.sqlalchemy.org/docs/orm/session.html#merging

Stefano,

Thanks for the reply. The problem I see with this approach is that I think it 
actually commits the new row to the database.  In the app, it's possible that 
the user could decide to cancel before inserting the new row.  Of course, I 
could back out the addition, but it seems like it would be better to not insert 
in the first place.

Mark

-- 
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.



Re: [sqlalchemy] Declarative Field Type 'Alias'

2011-08-05 Thread Mark Erbaugh

On Aug 5, 2011, at 3:51 PM, Michael Bayer wrote:

 On Aug 5, 2011, at 1:36 PM, Mark Erbaugh wrote:
 
 In my application, some tables have several fields that need to have the 
 same type and default value, i.e.:
 
 field1 = Column(Integer, default=2)
 field2 = Column(Integer, default=2)
 ...
 
 Is there some way to refactor the Common(Integer, default=2), short of 
 creating a custom column type?  I could see the possibility that in a future 
 version of the application, I would want to globally change the column type 
 or default value for all these fields at once.
 
 So far, I've come up with creating a function that returns the column.
 
 def common_field():
  return Column(Integer, default=2)
 
 field1 = common_field()
 field2 = common_field()
 
 Is there a better way?
 
 What's the issue with using a function to generate a Column of a certain 
 pre-determined configuration (what are functions in a procedural language for 
 if not this) ?  


No issue at all.  I just wanted to make sure I was doing it 'the right way'.  I 
just noticed that in several places, SA will let you pass in a class or an 
instance of a class and figures out what to do with it.  I thought that 
something like that might be working here.

Actually, there is a small issue with using a function: Where should the 
function live?  Obviously for some schema, this field type is used in multiple 
tables and belongs in a global namespace, but for others (as in my 
application), the field type is unique to an individual table. It would be nice 
if the function could live in the class's namespace.

This is more of a Python issue than a SA issue, but I had trouble getting this 
to work. I did, but the code seems a little awkard to me sigh.  In addition 
to the requirements already, I also wanted toe default value to be a class 
level 'constant'.  The problem, as I see it, is that since the class definition 
isn't complete, it's namespace isn't avaialble.  Since the default value 
'constant' is a class data member, it would make sense if the function were a 
@classmethod, but I couldn't get python to accept:

class  Table(Base):

...

DEFAULT = 2

@classmethod
def CustomColumn(cls):
return Column(Integer, default=DEFAULT)

...

field1 = CustomColumn()

Python complained 'classmethod object is not callable' on the last line above.

Next I tried changing that line to:

field1 = Table.CustomColumn()

Now Python complained 'Table' is not  defined

If I leave the @classmethod decroator off, I couldn't figure out how to 
reference the class level data DEFAULT.

Python complained on the return Column(... line ' global name DEFAULT is not 
defined.

What I finally ended up with that works is:

class Table(Base):
...
DEFAULT = 2

def CustomColumn(default=DEFAULT):
return Column(Integer, default=default)

...

field1 = CustomColumn()

Mark


-- 
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.



Re: [sqlalchemy] Populate sample data

2011-08-04 Thread Mark Erbaugh

On Aug 4, 2011, at 9:22 AM, Michael Bayer wrote:

 The range of speedups here would be between 30% and 80%, with direct usage of 
 connection/session .execute() with Table metadata giving you the 80%.

Thanks. I'll look into your suggestions

 
 I'm not sure what transaction is in transaction.begin() , if you're using a 
 regular SQLAlchemy Session in it is always in a transaction in that it uses 
 a single connection until rollback() or commit() is called.

Originally, I thought transaction was from the standard Python library, but 
upon research, it looks like it's from the transaction package that is part of 
Zope. It's included in the Pyramid installation.

Mark

-- 
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.



Re: [sqlalchemy] Populate sample data

2011-08-04 Thread Mark Erbaugh

On Aug 4, 2011, at 9:22 AM, Michael Bayer wrote:

 
 On Aug 3, 2011, at 8:38 PM, Mark Erbaugh wrote:
 
 I'm using SA (with SQLite) with a schema like:
 
 A - B - C - D
 
 where - means that the tables have a one to many relationship
 
 I'm populating  a sample data set where there are 25 rows in A, 25 rows in B 
 for each row in A, 25 rows in C for each row in B and 25 rows in D for each 
 row in C.  This results in about 390k rows in D.  The database itself is 
 only about 12 MB, but it takes a long time (several minutes) to write the 
 data to the file.
 
 I'm taking the approach of appending items to the table's relationship 
 column.
 
 for i in range(25):
  x = A()
  session.add(A)
  for j in range(25):
  y = B()
  x.b.append(y)
  for k in range(25):
  z = C()
  y.c.append(z)
  for  l in range(25):
  xx = D()
  z.d.append(xx)
 session.flush()


Thanks again for the help.  I decided to time the various approaches.  My 
original approach took 4:23 (minutes: seconds). Note: all my times included 
data generation and insertion into a SQLite on-disk database.

 The biggest speed variable in a mass INSERT operation is whether or not 
 individual cursor.execute() calls, or a small handful of cursor.executemany() 
 calls each with thousands of rows, are used.
 
 With the ORM, a mass executemany() is used for INSERT in the case that 
 primary key values are already present in the given objects.   If not, the 
 ORM has to INSERT each A() row one at a time, get the new primary key value, 
 and then later populate 25*25 B() object's foreign key with the A.id value; 
 then this goes down to the B()-C() area, etc.
 
 So if A(), B(), C(), D() can be created with id=5, id=6, etc., assuming 
 id is the primary key, the ORM should be able to bunch lots of rows 
 together into one cursor.executemany() call and you'll see an immediate, 
 dramatic speedup.


This took 3:36

 
 The next level would be if you populated the a_id, b_id, 
 foreign-key-to-parent columns directly instead of using append().If you 
 did a profile on your script you'd see lots of time taken in many places, but 
 all those append() operations would be one of them, as well as lots of event 
 firing and bookkeeping that SQLAlchemy has to do when they occur, both at 
 append() time as well as within the flush() (populating the primary key 
 values to foreign key attributes).


This took 2:28

 By far the fastest way to do this would be to use 
 session.execute(a_table.insert(), [rows]), 
 session.execute(b_table.insert(), [rows]), etc.   That is, assemble the 
 whole set of A, B, C, D, directly in terms of the mapped table,  or better 
 yet do it in chunks, perhaps drill down through B, C, D for a single A then 
 insert everything, etc.That way you optimize how these rows are 
 constructed in Python exactly to the pattern that corresponds directly to the 
 database structure, instead of having SQLAlchemy decode the database 
 structure from an object hierarchy.  An insertmany is documented at 
 http://www.sqlalchemy.org/docs/core/tutorial.html#executing-multiple-statements.
The ORM Session has an execute() method just like Connection does.

I did this with one session.execute for each table, rather than chunks. It took 
0:46

 The range of speedups here would be between 30% and 80%, with direct usage of 
 connection/session .execute() with Table metadata giving you the 80%.

Mark


-- 
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] One to many, but only load one

2011-08-04 Thread Mark Erbaugh
Table A has a one to many relationship with Table B.  There may be zero or more 
rows in B for each row in A.

I would like to have a query that retrieves all the rows in table A joined with 
the first related row in table B (if one exists). In this case, each row in 
table B has a DATE field and I want to retrieve the row with the latest date.  
Is this possible using joinedload?

Thanks,
Mark

-- 
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.



Re: [sqlalchemy] One to many, but only load one

2011-08-04 Thread Mark Erbaugh
Thanks,

Could you explain how to do contains_eager with an explicit query().  I tried 
putting a query inside a call to contains_eager, but get an error:

ArgumentError: mapper option expects string key or list of attributes

Mark

On Aug 4, 2011, at 6:39 PM, Michael Bayer wrote:

 awkardly and inefficiently from a SQL perspective.   contains_eager() with an 
 explicit query() would produce better result
 
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base
 Base = declarative_base()
 import datetime
 
 class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
bs = relationship(B)
 
 class B(Base):
__tablename__ = 'b'
id = Column(Integer, primary_key=True)
a_id = Column(Integer, ForeignKey('a.id'))
date = Column(Date)
 
 A.latest_b = relationship(B, 
primaryjoin=and_(
A.id==B.a_id, 

 B.date==select([func.max(B.date)]).where(B.a_id==A.id).correlate(A.__table__)
)
)
 
 e = create_engine('sqlite://', echo=True)
 Base.metadata.create_all(e)
 s = Session(e)
 
 s.add_all([
A(bs=[
B(date=datetime.date(2011, 10, 5)),
B(date=datetime.date(2011, 8, 4)),
B(date=datetime.date(2011, 9, 17)),
]),
A(bs=[
B(date=datetime.date(2011, 10, 5)),
B(date=datetime.date(2011, 8, 4)),
B(date=datetime.date(2011, 9, 17)),
]),
 ])
 s.commit()
 
 for obj in s.query(A).options(joinedload(A.latest_b)):
print obj.latest_b
 
 
 
 On Aug 4, 2011, at 5:55 PM, Mark Erbaugh wrote:
 
 Table A has a one to many relationship with Table B.  There may be zero or 
 more rows in B for each row in A.
 
 I would like to have a query that retrieves all the rows in table A joined 
 with the first related row in table B (if one exists). In this case, each 
 row in table B has a DATE field and I want to retrieve the row with the 
 latest date.  Is this possible using joinedload?
 
 Thanks,
 Mark
 
 -- 
 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.
 
 
 -- 
 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.
 

-- 
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] Populate sample data

2011-08-03 Thread Mark Erbaugh
I'm using SA (with SQLite) with a schema like:

A - B - C - D

where - means that the tables have a one to many relationship

I'm populating  a sample data set where there are 25 rows in A, 25 rows in B 
for each row in A, 25 rows in C for each row in B and 25 rows in D for each row 
in C.  This results in about 390k rows in D.  The database itself is only about 
12 MB, but it takes a long time (several minutes) to write the data to the file.

I'm taking the approach of appending items to the table's relationship column.

for i in range(25):
x = A()
session.add(A)
for j in range(25):
y = B()
x.b.append(y)
for k in range(25):
z = C()
y.c.append(z)
for  l in range(25):
xx = D()
z.d.append(xx)
session.flush()


The bulk of the delay seems to be the session.flush call.

I'm using the Pyramid framework which used Python's transaction module.  I call 
transaction.begin() prior to adding the rows. According to the SQLite FAQ, this 
should speed things up.

Are there any suggestions on how to speed things up?

Thanks,
Mark

-- 
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] SA Unicode and SQLite

2011-08-02 Thread Mark Erbaugh
I'm trying to follow the instructions in the SA docs regarding Unicode and 
SQLite.  I've declared all my character fields as either Unicode or 
UnicodeText.  When populating the data, I specify strings as unicode strings 
(u'string'), but I'm still getting an warning: SAWarning Unicode type received 
non-unicode bind parameter, when I initially populate the database.  On the 
next line, it reports param.append(processors[key](compiled_params[key])).  Is 
this supposed to be telling me what the errant bind parameter is?

I've turned on echo and looking at the queries and parameters, all the 
character parameters are specified as unicode strings, except for the dates 
which are given like '2011-08-02'.  Are the dates what's causing the 
non-unicode bind parameter warning?

I'm using SQLAlchemy 0.7.1, with Python 2.7.2

Thanks,
Mark

-- 
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.



Re: [sqlalchemy] SA Unicode and SQLite

2011-08-02 Thread Mark Erbaugh

On Aug 2, 2011, at 6:50 PM, Michael Bayer wrote:

 
 On Aug 2, 2011, at 6:35 PM, Mark Erbaugh wrote:
 
 I'm trying to follow the instructions in the SA docs regarding Unicode and 
 SQLite.  I've declared all my character fields as either Unicode or 
 UnicodeText.  When populating the data, I specify strings as unicode strings 
 (u'string'), but I'm still getting an warning: SAWarning Unicode type 
 received non-unicode bind parameter, when I initially populate the database. 
  On the next line, it reports 
 param.append(processors[key](compiled_params[key])).  Is this supposed to be 
 telling me what the errant bind parameter is?
 
 I've turned on echo and looking at the queries and parameters, all the 
 character parameters are specified as unicode strings, except for the dates 
 which are given like '2011-08-02'.  Are the dates what's causing the 
 non-unicode bind parameter warning?
 
 I'm using SQLAlchemy 0.7.1, with Python 2.7.2
 
 Set the warnings filter to error and send off a stack trace, that will show 
 exactly where the offending statement is (its not impossible that its within 
 SQLA too).
 
 import warnings
 warnings.simplefilter(error)
 
 http://docs.python.org/library/warnings.html
 

Thanks, that did the trick.

Mark

-- 
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] Read-Only Database

2011-06-21 Thread Mark Erbaugh
My program accesses a sqlite database. It only extracts data from the database, 
it never writes anything to it.  It can also be assumed that the database is 
not updated by other processes. In reality, the database is completely replaced 
periodically by a new version, but the program can be shut down and re-started 
whenever that happens.

Is there a way to tell SQLAlchemy that the database is read-only, and would 
that simplify the work that SA does behind the scenes?


Thanks,
Mark


-- 
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.



  1   2   >