[sqlalchemy] Re: Is there any potential problem to store datetime as strings in one column?

2015-03-30 Thread Bao Niu


On Monday, March 23, 2015 at 7:53:31 AM UTC-7, Jonathan Vanasco wrote:



 On Sunday, March 22, 2015 at 7:01:35 PM UTC-4, Bao Niu wrote:

 Also because sql datetime datatype doesn't persist timezone information. 
 Therefore, I tried to store all the time information as strings.


 If your database doesn't support timezones, I think it would be easiest to 
 convert everything to UTC as a Datetime and then add a second INT column 
 with the time zone offset.You can create a property method on 
 SqlAlchemy models to create a new 'timestamp_display' out of both columns. 
  (you might even be able to write a custom column type)

 That approach will let you do all the in-database sorting you need, and 
 then use the offset to customize the time for display.  If you store as 
 strings, you'll lose all the benefits of the database's datetime 
 sorting/searching/miscellaneous functions and have to write custom 
 compatibility in SQL/SqlAlchemy.  that is a lot more work than splitting 
 the data into 2 columns.




Hi Jonathan,

To make sure that I understand it right, did you mean hybrid attribute 
methods when you mentioned property methods here? 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Is there any potential problem to store datetime as strings in one column?

2015-03-22 Thread Bao Niu
Hi,

Is there any potential disadvantages in using string as the datatype to 
store datetime plus timezone in one column?
In my application the time information is not uniform. Some rows are 
datetime while others just date. I still want to store everything in one 
column, named time_point. Also because sql datetime datatype doesn't 
persist timezone information. Therefore, I tried to store all the time 
information as strings.

In my simple application the query seems to be fine, but I wonder what 
disadvantages can this bring so that this method is not popular among 
experienced programmers. Are there any particular situations where using 
string to store datetime information can do more harm than good?

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


[sqlalchemy] Is there a tool/library that visually renders SQLAlchemy classes as UMLs or something similar?

2015-02-12 Thread Bao Niu
Is there a tool/library that visually presents all many-to-many 
relationships defined in a module using SQLAlchemy?
I used to use an online database designer that automatically converts the 
diagram to SQLs, which is magical. Is there a similar tool that works with 
SQLAlchemy classes? Preferably allows me to edit(including add, remove and 
change in place) on the diagrams when I'm viewing it.
oh, this tool ideally is so smart that it only draws diagrams of 
SQLAlchemy class, leaving other classes out of sight of the diagram 
rendered. Anyone know of such a tool exists?

-- 
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] Why is assignment of a transient parent object does not automatically add this parent object into the session?

2015-02-10 Thread Bao Niu
I guess what I must do immediately is to get myself a pair of new
glasses...Thank you Simon!

On Tue, Feb 10, 2015 at 2:36 PM, Simon King si...@simonking.org.uk wrote:

 On 10 Feb 2015, at 22:14, Bao Niu niuba...@gmail.com wrote:
 
  Why is assignment of a transient parent object does not automatically
 add this parent object into the session? But Parent.append(PersistedChild)
 will do the job nicely?
  Here is my code:
 
  from sqlalchemy import Column, String, Integer, ForeignKey
  from sqlalchemy import create_engine
  from sqlalchemy.orm import sessionmaker
  from sqlalchemy.orm import relationship, backref
  from sqlalchemy.ext.declarative import declarative_base
 
  Base = declarative_base()
 
  class Department(Base):
  __tablename__ = 'department'
  id = Column(Integer, primary_key=True)
  name = Column(String)
 
  class Employee(Base):
  __tablename__ = 'employee'
  id = Column(Integer, primary_key=True)
  name = Column(String)
  department_id = Column(Integer, ForeignKey('department.id'))
  department = relationship(Department, backref=backref('employees',
 uselist=True))
 
  engine = create_engine('sqlite:///')
  session = sessionmaker()
  session.configure(bind=engine)
  Base.metadata.create_all(engine)
  s = session()
  john = Employee(name='john')
  it_department = Department(name='IT')
  print(john in s) # should be False
  print(it_department in s) # should be False
  s.add(john)
  print(john in s) # should be True
  print(it_department in s) # should be False
  john.departments = it_department # here I expect it_department(the
 Parent Object) would be automatically added to s in a cascade way, because
 of the backref
  print(john in s) # should be True
  print(it_department in s) # should be True, however this is not true.
 

 I don’t know if this is the problem, but you appear to have a typo:

   john.departments = it_department

 ...but the relationship is called “department”, not “departments”

 HTH,

 Simon

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/3EE9dZHpNj4/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] Why is assignment of a transient parent object does not automatically add this parent object into the session?

2015-02-10 Thread Bao Niu
Why is assignment of a transient parent object does not automatically add 
this parent object into the session? But Parent.append(PersistedChild) will 
do the job nicely?
Here is my code:

from sqlalchemy import Column, String, Integer, ForeignKey
 from sqlalchemy import create_engine
 from sqlalchemy.orm import sessionmaker
 from sqlalchemy.orm import relationship, backref
 from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

 class Department(Base):
 __tablename__ = 'department'
 id = Column(Integer, primary_key=True)
 name = Column(String)

 class Employee(Base):
 __tablename__ = 'employee'
 id = Column(Integer, primary_key=True)
 name = Column(String)
 department_id = Column(Integer, ForeignKey('department.id'))
 department = relationship(Department, backref=backref('employees', 
 uselist=True))

 engine = create_engine('sqlite:///')
 session = sessionmaker()
 session.configure(bind=engine)
 Base.metadata.create_all(engine)
 s = session()
 john = Employee(name='john')
 it_department = Department(name='IT')
 print(john in s) # should be False
 print(it_department in s) # should be False
 s.add(john)
 print(john in s) # should be True
 print(it_department in s) # should be False
 john.departments = it_department # here I expect it_department(the Parent 
 Object) would be automatically added to s in a cascade way, because of the 
 backref
 print(john in s) # should be True
 print(it_department in s) # should be True, however this is not true.


-- 
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] dealing with column comments

2015-01-10 Thread Bao Niu
I wonder if there is a method/inspector in SQLAlchemy that allows me to 
set/access column comments residing in sqlite database schema? I know I can 
access it through PRAGMA table_info, I just wonder if I can do this 
directly in SA? I've searched the documentation but didn't find anything 
related. 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Python 3, Unicode column types and MetaData.reflect()

2015-01-07 Thread Bao Niu
Thanks Michael. I should form a habit of trying it. It wasn't because I
didn't want to, it was because I always fear that if I'm not careful with
data I could ruin the precious data at one keystroke. So I kind of always
ask before doing, lol.


On Wed, Jan 7, 2015 at 3:47 PM, Michael Bayer mike...@zzzcomputing.com
wrote:


 Hi Bao -

 Why don’t you just try it?   As I’ve said, pysqlite returns unicode for
 strings already so the SQLAlchemy type isn’t really important except in
 some in-Python expression situations (like getting the + operator to do
 string concatenation).

 Your table is returning everything as NullType because that table def
 doesn’t actually have any types in it.




 Bao Niu niuba...@gmail.com wrote:

  Hi Michael, I don't have any problem having them all as NullType, but I
 just want to make sure the SQLite will deal with smoothly even when they
 are actually not NullType but Unicode/UnicodeText types. May I just go
 ahead and use NullType here instead of explicitly re-define all those
 columns as Unicode/UnicodeText? Please give a little hint here. Thanks.
 
  On Wed, Jan 7, 2015 at 1:06 PM, Bao Niu niuba...@gmail.com wrote:
  Here is what I got from sqlite select sql from sqlite_master where
 name=‘tablename’;
 
  CREATE TABLE persons (ID ,名 ,中间名 ,姓 ,类别 ,生日 ,主要电话
 ,住宅传真 ,住宅地址国家地区 ,住宅地址市县 ,住宅地址街道 ,住宅地址邮政编码 ,住宅电话 ,住宅电话2
 ,其他传真 ,其他地址国家地区 ,其他地址市县 ,其他地址省市自治区 ,其他地址街道 ,其他地址邮政编码 ,其他电话
 ,办公地点 ,单位 ,单位主要电话 ,商务传真 ,商务地址国家地区 ,商务地址市县 ,商务地址省市自治区
 ,商务地址街道 ,商务地址邮政编码 ,商务电话 ,商务电话2 ,寻呼机 ,无绳电话 ,电子邮件2地址 ,电子邮件3地址
 ,电子邮件地址 ,移动电话 ,经理姓名 ,网页 ,职务 ,部门 ,配偶 ,附注 )
 
 
  Sorry for all non-ASCII characters, those are my native language32B.gif
 
  On Wed, Jan 7, 2015 at 9:53 AM, Michael Bayer mike...@zzzcomputing.com
 wrote:
  the two cases where NullType() is still returned are if the type is
 defined as BLOB or as NULL in the SQLAlchemy database.  change those and
 you won’t get any NullType.   post your table defs here using:
 
  sqlite select sql from sqlite_master where name=‘tablename’;
 
 
 
 
 
  Bao Niu niuba...@gmail.com wrote:
 
   Thank you Michael.
  
   I've read the documentation that you quoted very carefully but still
 not very sure in my case. You said that since 0.9.3 this issue has been
 resolved, but I'm using 0.9.8 on Ubuntu and still get NullTypes. If I'm
 using sqlalchemy MetaData.reflect() or automap extensions, together with
 SQLite database, I do not need to worry about these Unicode issues? Is
 there a newbie-friendly configuration step-by-step tutorial on this issue?
 Thanks.
  
   On Mon, Jan 5, 2015 at 4:56 PM, Michael Bayer 
 mike...@zzzcomputing.com wrote:
  
  
   Bao Niu niuba...@gmail.com wrote:
  
   
I have a couple of questions regarding the Unicode/UnicodeText
 column type here.
   
1) I'm using Python 3, do I still need to explicitly use
 Unicode/UnicodeText type to define my columns? I thought Python 3
 inherently supports unicode?
  
   it does, but your database (often) does not.  the unicode-ness defines
 the storage of the type on the DB side, not as much the conversion on the
 Python side which you can get with convert_unicode=True.  Sqlite has native
 unicode on both py2k and py3k so not a big deal there.
  
   
2) If I use MetaData.reflect(), it seems to me that all the columns
 are reflected to be NullType(), regardless how I set it in the database.
 How can I overcome this?
  
   SQLite doesn’t have real “types”, so up until version 0.9.2 we only
 reflect whats given for a fixed set of names.  as of 0.9.3 we always
 resolve to an affinity so you should never get null type:
  
  
 http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#type-reflection
  
  
  
  
  
What I did is like this:
import sqlalchemy
   
   
eng = sqlalchemy.create_engine('sqlite:///foobar.db')
meta2 = sqlalchemy.MetaData(eng)
meta2.reflect()
   
meta2.tables['entries'].c['foo'].type
   
   
and I got NullType here even though I'm pretty sure I defined it to
 unicode in my database.
   
--
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.
  
   --
   You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
   To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/BrFN-qjkrqY/unsubscribe.
   To unsubscribe from this group and all its topics, 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] Python 3, Unicode column types and MetaData.reflect()

2015-01-07 Thread Bao Niu
Here is what I got from sqlite select sql from sqlite_master where
name=‘tablename’;

CREATE TABLE persons (ID ,名 ,中间名 ,姓 ,类别 ,生日 ,主要电话 ,住宅传真
 ,住宅地址国家地区 ,住宅地址市县 ,住宅地址街道 ,住宅地址邮政编码 ,住宅电话 ,住宅电话2 ,其他传真
 ,其他地址国家地区 ,其他地址市县 ,其他地址省市自治区 ,其他地址街道 ,其他地址邮政编码 ,其他电话 ,办公地点
 ,单位 ,单位主要电话 ,商务传真 ,商务地址国家地区 ,商务地址市县 ,商务地址省市自治区 ,商务地址街道
 ,商务地址邮政编码 ,商务电话 ,商务电话2 ,寻呼机 ,无绳电话 ,电子邮件2地址 ,电子邮件3地址 ,电子邮件地址
 ,移动电话 ,经理姓名 ,网页 ,职务 ,部门 ,配偶 ,附注 )


Sorry for all non-ASCII characters, those are my native language[?]

On Wed, Jan 7, 2015 at 9:53 AM, Michael Bayer mike...@zzzcomputing.com
wrote:

 the two cases where NullType() is still returned are if the type is
 defined as BLOB or as NULL in the SQLAlchemy database.  change those and
 you won’t get any NullType.   post your table defs here using:

 sqlite select sql from sqlite_master where name=‘tablename’;





 Bao Niu niuba...@gmail.com wrote:

  Thank you Michael.
 
  I've read the documentation that you quoted very carefully but still not
 very sure in my case. You said that since 0.9.3 this issue has been
 resolved, but I'm using 0.9.8 on Ubuntu and still get NullTypes. If I'm
 using sqlalchemy MetaData.reflect() or automap extensions, together with
 SQLite database, I do not need to worry about these Unicode issues? Is
 there a newbie-friendly configuration step-by-step tutorial on this issue?
 Thanks.
 
  On Mon, Jan 5, 2015 at 4:56 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:
 
 
  Bao Niu niuba...@gmail.com wrote:
 
  
   I have a couple of questions regarding the Unicode/UnicodeText column
 type here.
  
   1) I'm using Python 3, do I still need to explicitly use
 Unicode/UnicodeText type to define my columns? I thought Python 3
 inherently supports unicode?
 
  it does, but your database (often) does not.  the unicode-ness defines
 the storage of the type on the DB side, not as much the conversion on the
 Python side which you can get with convert_unicode=True.  Sqlite has native
 unicode on both py2k and py3k so not a big deal there.
 
  
   2) If I use MetaData.reflect(), it seems to me that all the columns
 are reflected to be NullType(), regardless how I set it in the database.
 How can I overcome this?
 
  SQLite doesn’t have real “types”, so up until version 0.9.2 we only
 reflect whats given for a fixed set of names.  as of 0.9.3 we always
 resolve to an affinity so you should never get null type:
 
 
 http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#type-reflection
 
 
 
 
 
   What I did is like this:
   import sqlalchemy
  
  
   eng = sqlalchemy.create_engine('sqlite:///foobar.db')
   meta2 = sqlalchemy.MetaData(eng)
   meta2.reflect()
  
   meta2.tables['entries'].c['foo'].type
  
  
   and I got NullType here even though I'm pretty sure I defined it to
 unicode in my database.
  
   --
   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.
 
  --
  You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
  To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/BrFN-qjkrqY/unsubscribe.
  To unsubscribe from this group and all its topics, 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.
 
 
  --
  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.

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/BrFN-qjkrqY/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


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

Re: [sqlalchemy] Python 3, Unicode column types and MetaData.reflect()

2015-01-07 Thread Bao Niu
Hi Michael, I don't have any problem having them all as NullType, but I
just want to make sure the SQLite will deal with smoothly even when they
are actually not NullType but Unicode/UnicodeText types. May I just go
ahead and use NullType here instead of explicitly re-define all those
columns as Unicode/UnicodeText? Please give a little hint here. Thanks.

On Wed, Jan 7, 2015 at 1:06 PM, Bao Niu niuba...@gmail.com wrote:

 Here is what I got from sqlite select sql from sqlite_master where
 name=‘tablename’;

 CREATE TABLE persons (ID ,名 ,中间名 ,姓 ,类别 ,生日 ,主要电话 ,住宅传真
 ,住宅地址国家地区 ,住宅地址市县 ,住宅地址街道 ,住宅地址邮政编码 ,住宅电话 ,住宅电话2 ,其他传真
 ,其他地址国家地区 ,其他地址市县 ,其他地址省市自治区 ,其他地址街道 ,其他地址邮政编码 ,其他电话 ,办公地点
 ,单位 ,单位主要电话 ,商务传真 ,商务地址国家地区 ,商务地址市县 ,商务地址省市自治区 ,商务地址街道
 ,商务地址邮政编码 ,商务电话 ,商务电话2 ,寻呼机 ,无绳电话 ,电子邮件2地址 ,电子邮件3地址 ,电子邮件地址
 ,移动电话 ,经理姓名 ,网页 ,职务 ,部门 ,配偶 ,附注 )


 Sorry for all non-ASCII characters, those are my native language[?]

 On Wed, Jan 7, 2015 at 9:53 AM, Michael Bayer mike...@zzzcomputing.com
 wrote:

 the two cases where NullType() is still returned are if the type is
 defined as BLOB or as NULL in the SQLAlchemy database.  change those and
 you won’t get any NullType.   post your table defs here using:

 sqlite select sql from sqlite_master where name=‘tablename’;





 Bao Niu niuba...@gmail.com wrote:

  Thank you Michael.
 
  I've read the documentation that you quoted very carefully but still
 not very sure in my case. You said that since 0.9.3 this issue has been
 resolved, but I'm using 0.9.8 on Ubuntu and still get NullTypes. If I'm
 using sqlalchemy MetaData.reflect() or automap extensions, together with
 SQLite database, I do not need to worry about these Unicode issues? Is
 there a newbie-friendly configuration step-by-step tutorial on this issue?
 Thanks.
 
  On Mon, Jan 5, 2015 at 4:56 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:
 
 
  Bao Niu niuba...@gmail.com wrote:
 
  
   I have a couple of questions regarding the Unicode/UnicodeText column
 type here.
  
   1) I'm using Python 3, do I still need to explicitly use
 Unicode/UnicodeText type to define my columns? I thought Python 3
 inherently supports unicode?
 
  it does, but your database (often) does not.  the unicode-ness defines
 the storage of the type on the DB side, not as much the conversion on the
 Python side which you can get with convert_unicode=True.  Sqlite has native
 unicode on both py2k and py3k so not a big deal there.
 
  
   2) If I use MetaData.reflect(), it seems to me that all the columns
 are reflected to be NullType(), regardless how I set it in the database.
 How can I overcome this?
 
  SQLite doesn’t have real “types”, so up until version 0.9.2 we only
 reflect whats given for a fixed set of names.  as of 0.9.3 we always
 resolve to an affinity so you should never get null type:
 
 
 http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#type-reflection
 
 
 
 
 
   What I did is like this:
   import sqlalchemy
  
  
   eng = sqlalchemy.create_engine('sqlite:///foobar.db')
   meta2 = sqlalchemy.MetaData(eng)
   meta2.reflect()
  
   meta2.tables['entries'].c['foo'].type
  
  
   and I got NullType here even though I'm pretty sure I defined it to
 unicode in my database.
  
   --
   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.
 
  --
  You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
  To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/BrFN-qjkrqY/unsubscribe.
  To unsubscribe from this group and all its topics, 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.
 
 
  --
  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.

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/BrFN-qjkrqY/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com

Re: [sqlalchemy] Python 3, Unicode column types and MetaData.reflect()

2015-01-06 Thread Bao Niu
Thank you Michael.

I've read the documentation that you quoted very carefully but still not
very sure in my case. You said that since 0.9.3 this issue has been
resolved, but I'm using 0.9.8 on Ubuntu and still get NullTypes. If I'm
using sqlalchemy MetaData.reflect() or automap extensions, together with
SQLite database, I do not need to worry about these Unicode issues? Is
there a newbie-friendly configuration step-by-step tutorial on this issue?
Thanks.

On Mon, Jan 5, 2015 at 4:56 PM, Michael Bayer mike...@zzzcomputing.com
wrote:



 Bao Niu niuba...@gmail.com wrote:

 
  I have a couple of questions regarding the Unicode/UnicodeText column
 type here.
 
  1) I'm using Python 3, do I still need to explicitly use
 Unicode/UnicodeText type to define my columns? I thought Python 3
 inherently supports unicode?

 it does, but your database (often) does not.  the unicode-ness defines the
 storage of the type on the DB side, not as much the conversion on the
 Python side which you can get with convert_unicode=True.  Sqlite has native
 unicode on both py2k and py3k so not a big deal there.

 
  2) If I use MetaData.reflect(), it seems to me that all the columns are
 reflected to be NullType(), regardless how I set it in the database. How
 can I overcome this?

 SQLite doesn’t have real “types”, so up until version 0.9.2 we only
 reflect whats given for a fixed set of names.  as of 0.9.3 we always
 resolve to an affinity so you should never get null type:

 http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#type-reflection





  What I did is like this:
  import sqlalchemy
 
 
  eng = sqlalchemy.create_engine('sqlite:///foobar.db')
  meta2 = sqlalchemy.MetaData(eng)
  meta2.reflect()
 
  meta2.tables['entries'].c['foo'].type
 
 
  and I got NullType here even though I'm pretty sure I defined it to
 unicode in my database.
 
  --
  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.

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/BrFN-qjkrqY/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] Python 3, Unicode column types and MetaData.reflect()

2015-01-05 Thread Bao Niu

I have a couple of questions regarding the Unicode/UnicodeText column type 
here.

1) I'm using Python 3, do I still need to explicitly use 
Unicode/UnicodeText type to define my columns? I thought Python 3 
inherently supports unicode? 

2) If I use MetaData.reflect(), it seems to me that all the columns are 
reflected to be NullType(), regardless how I set it in the database. How 
can I overcome this?
What I did is like this:
import sqlalchemy


eng = sqlalchemy.create_engine('sqlite:///foobar.db')
meta2 = sqlalchemy.MetaData(eng)
meta2.reflect()

meta2.tables['entries'].c['foo'].type


and I got NullType here even though I'm pretty sure I defined it to unicode 
in my database.

-- 
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] How to reveal a certain relationship's cascade mode at runtime?

2014-07-29 Thread Bao Niu
I am using automap. I am not sure about the configuration of certain 
relationships' cascade. Is there a way to find it out at runtime?

class User(sql_base):
 __tablename__ = user

class Address(sql_base):
__tablename__ = address

sql_base.prepare(sa_engine, reflect=True)

-- 
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] Re: For a better understanding of merge()

2014-07-24 Thread Bao Niu

Could somebody help clarify this difference between *reconciling* and 
*stamp*(load=True vs. load=False) with session.merge(), ideally by an 
example? Thanks very much.

On Thursday, July 17, 2014 8:01:42 PM UTC-7, Bao Niu wrote:

 If the load=True flag is left at its default, this copy process emits 
 events and will load the target object’s unloaded collections for each 
 attribute present on the source object, so that the incoming state can be 
 reconciled against what’s present in the database. If load is passed as 
 False, the incoming data is “stamped” directly without producing any 
 history.


 I have a question regarding the above section:
 What exactly is the difference between *reconciling* and *stamp*(load=True 
 vs. load=False)? These two abstract words really are not quite clear for a 
 beginner to understand it. I would suppose that the end result would always 
 be the source object's state being completely transferred onto the target 
 object. I couldn't see any difference between *reconciling* and *stamp*. 
 Could someone give an example here to illustrate the purpose of this 
 parameter?
 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Re: Mechanism of reconciling for merge method

2014-07-17 Thread Bao Niu
Probably what is abstruse here is the jargon emitting history events, is 
it something as a newbie must understand in order to use Session properly? 
As a beginner should I know this before studying Session section? I'd 
appreciate some insight from pros. Thanks.

On Tuesday, July 15, 2014 5:57:59 PM UTC-7, Bao Niu wrote:

 In the documentation for *session.merge()* method, there is a section on 
 the mechanism of reconciling if the *load=true* is set:

 If the load=True flag is left at its default, this copy process emits 
 events and will load the target object’s unloaded collections for each 
 attribute present on the source object, so that the incoming state can be 
 reconciled against what’s present in the database. If load is passed as 
 False, the incoming data is “stamped” directly without producing any 
 history.

  
 I don't quite understand the relationship between stamped and without 
 stamped. The author is apparently trying to contrast something important 
 here, but I just couldn't imagine what a stamp could be here. Could someone 
 explain this process in a newbie-friendlier way please? 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Re: Mechanism of reconciling for merge method

2014-07-17 Thread Bao Niu
For example, if I have User class which is mapped to user table. In user 
table there is a single row, whose id (primary key) equals 1, like this:

 id |  name | gender | address
 1 John   male second best bathroom street, toilet#2

now I have this code:

 u = User(id=1)
 session.merge(u)
 session.commit()

because the incoming data contains only id attribute and nothing more, 
should I expect after execution the above code will wipe out that row and 
get something like this:

 id |  name | gender | address
 1 Null   Null  Null


My reason for such expectation is because of this in documentation:

  For mapped attributes which aren’t present on the source, the attribute 
 is expired on the target instance, discarding its existing value.


By the way, does this have something to do with If load is passed as 
False, the incoming data is *stamped* directly ?
Thanks.

On Tuesday, July 15, 2014 5:57:59 PM UTC-7, Bao Niu wrote:

 In the documentation for *session.merge()* method, there is a section on 
 the mechanism of reconciling if the *load=true* is set:

 If the load=True flag is left at its default, this copy process emits 
 events and will load the target object’s unloaded collections for each 
 attribute present on the source object, so that the incoming state can be 
 reconciled against what’s present in the database. If load is passed as 
 False, the incoming data is “stamped” directly without producing any 
 history.

  
 I don't quite understand the relationship between stamped and without 
 stamped. The author is apparently trying to contrast something important 
 here, but I just couldn't imagine what a stamp could be here. Could someone 
 explain this process in a newbie-friendlier way please? 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] For a better understanding of merge()

2014-07-17 Thread Bao Niu


 If the load=True flag is left at its default, this copy process emits 
 events and will load the target object’s unloaded collections for each 
 attribute present on the source object, so that the incoming state can be 
 reconciled against what’s present in the database. If load is passed as 
 False, the incoming data is “stamped” directly without producing any 
 history.


I have a question regarding the above section:
What exactly is the difference between *reconciling* and *stamp*(load=True 
vs. load=False)? These two abstract words really are not quite clear for a 
beginner to understand it. I would suppose that the end result would always 
be the source object's state being completely transferred onto the target 
object. I couldn't see any difference between *reconciling* and *stamp*. 
Could someone give an example here to illustrate the purpose of this 
parameter?
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Mechanism of reconciling for merge method

2014-07-15 Thread Bao Niu
In the documentation for *session.merge()* method, there is a section on 
the mechanism of reconciling if the *load=true* is set:

 If the load=True flag is left at its default, this copy process emits 
 events and will load the target object’s unloaded collections for each 
 attribute present on the source object, so that the incoming state can be 
 reconciled against what’s present in the database. If load is passed as 
 False, the incoming data is “stamped” directly without producing any 
 history.

 
I don't quite understand the relationship between stamped and without 
stamped. The author is apparently trying to contrast something important 
here, but I just couldn't imagine what a stamp could be here. Could someone 
explain this process in a newbie-friendlier way please? 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Is it considered bad practice to have more than one session instance simultaneously in a web application?

2014-07-14 Thread Bao Niu
Thank you guys for your replies. These days I spent some time reading the
documentation on session to make sure I understand all the basics. After
reading, I still have trouble understanding the point that mapped objects
should not outlive the session from which they are originally queried.

In my case, a Person object loaded from database, having two attributes,
o.FirstName, and o.LastName, is expected to persist within the full
life-cycle of my application, not just a database session, because when you
query the object you just make it visible to the application, you are not
sure what you are going to flush into database at this moment. As Jonathan
pointed out, merging seems to be the only way to extend the lifespan of
those queried and mapped objects across different sessions.

What I suggested in my previous post is having two (series of) sessions,
one is responsible for querying and making FirstName(s) and LastName(s),
and possibly concatenating the two; while the other (series of) sessions is
responsible for holding all the Persons objects together and do some
further query on them.

Why is this design flawed?? Did I violate some fundamental principles here?
Thanks.


On Tue, Jul 1, 2014 at 8:24 AM, Jonathan Vanasco jonat...@findmeon.com
wrote:

 That design is definitely flawed.

 Read up on the ORM session documentation, and pay attention to Merging,

 The session encapsulates a bit of logic and a unit of work.  Once you
 close a session, the objects within it are considered to be out-of-phase.
  Accessing their attributes -- even only for a read -- requires a new
 database session/transaction to ensure that the data is the same.

 Sessions should generally last the length of a web request -- unless you
 have very specific business requirements that necessitate otherwise.  In
 your case, you don't.  Just start a session at the beginning of each
 request.  You'll overcomplicate everything otherwise.

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/CVIkd-WQiDM/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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 considered bad practice to have more than one session instance simultaneously in a web application?

2014-07-14 Thread Bao Niu
Thank you Simon for your informative reply! It's very information-rich and
give me a new perspective to reflect on my design.
It's really lucky for me to join this forum, I've been getting all such
bonus knowledge all along!:)


On Mon, Jul 14, 2014 at 5:48 AM, Simon King si...@simonking.org.uk wrote:

 I wouldn't say that you are violating a fundamental principle, I would
 just say that what you are suggesting isn't the normal structure of
 a web application.

 (Not that there is a normal structure for web applications really -
 it massively depends on the size of your audience. Something that
 works for a single user or a small number of users would be
 inappropriate for an application with vast numbers of users)

 If your web application keeps application state in its own process
 between requests, then you need to think very carefully about race
 conditions. For example, does your web application framework use
 threads? What happens if 2 requests try to operate on the same person
 at the same time?

 It also constrains your architecture if you want to scale up. If a
 web request loads the information it needs from the database,
 processes it, then flushes it back, then you can add multiple web
 frontend processes all talking to the same backend database. When a
 client makes an HTTP request, it doesn't matter which frontend handles
 that request, because all the state is in the database.

 Also, web requests tend to map quite nicely onto database
 transactions, which themselves are meant to be short lived. A
 long-lived database transaction has the potential to lock parts of the
 database, or at least increase the amount of accounting that the
 database has to do.

 It's possible that none of this matters for your application. If you
 only have a single user, the chance of threads clashing is fairly
 small. If you've come up with a solution that works for you, carry on
 :-)

 Hope that helps,

 Simon

 On Mon, Jul 14, 2014 at 12:07 PM, Bao Niu niuba...@gmail.com wrote:
  Thank you guys for your replies. These days I spent some time reading the
  documentation on session to make sure I understand all the basics. After
  reading, I still have trouble understanding the point that mapped objects
  should not outlive the session from which they are originally queried.
 
  In my case, a Person object loaded from database, having two attributes,
  o.FirstName, and o.LastName, is expected to persist within the full
  life-cycle of my application, not just a database session, because when
 you
  query the object you just make it visible to the application, you are not
  sure what you are going to flush into database at this moment. As
 Jonathan
  pointed out, merging seems to be the only way to extend the lifespan of
  those queried and mapped objects across different sessions.
 
  What I suggested in my previous post is having two (series of) sessions,
 one
  is responsible for querying and making FirstName(s) and LastName(s), and
  possibly concatenating the two; while the other (series of) sessions is
  responsible for holding all the Persons objects together and do some
 further
  query on them.
 
  Why is this design flawed?? Did I violate some fundamental principles
 here?
  Thanks.
 
 
  On Tue, Jul 1, 2014 at 8:24 AM, Jonathan Vanasco jonat...@findmeon.com
  wrote:
 
  That design is definitely flawed.
 
  Read up on the ORM session documentation, and pay attention to
 Merging,
 
  The session encapsulates a bit of logic and a unit of work.  Once you
  close a session, the objects within it are considered to be
 out-of-phase.
  Accessing their attributes -- even only for a read -- requires a new
  database session/transaction to ensure that the data is the same.
 
  Sessions should generally last the length of a web request -- unless you
  have very specific business requirements that necessitate otherwise.  In
  your case, you don't.  Just start a session at the beginning of each
  request.  You'll overcomplicate everything otherwise.
 

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/CVIkd-WQiDM/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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 considered bad practice to have more than one session instance simultaneously in a web application?

2014-06-30 Thread Bao Niu
Hi Simon,
Sorry for the poor explanation in my previous post.
Let me try to clarify this using a flow here:
---
1st_web_request comes in to tell the server which person instances are to
be interested. because it involves hybrid_property, and query, so it needs
a session here, let's call it session_#1;
==
entering a stage where session_#1 has to be active, or otherwise we will
lose sync ability to update those hybrid_property. At this stage session_#1
basically is just holding a bunch of queried associations of Person
instances and their names, and standing by, waiting for any update of
FirstName or LastName to construct a new hybrid_property of Full_Name on
the fly.
==
Now we have 2nd_web_request coming in, which carries a thread-local session
object of its own, let's call it collectively session_#2.(by the way I'm
using cherrypy and built a plugin and tool to automatically bind a session
for each request) I plan to use this second session object(s) to hold a
bunch of Person(not just their names, in comparison to session_#2).

My design breaks down here, as I really am lost in how I can deal with two
differently cycled session objects. Or maybe this design itself is flawed?
Maybe I there is something I missed about session as a whole?


On Mon, Jun 30, 2014 at 2:57 AM, Simon King si...@simonking.org.uk wrote:

 I'm not sure I understand your application. Are you saying that you
 have Person instances that stay in memory for longer than a single web
 request?

 Simon

 On Sun, Jun 29, 2014 at 11:54 AM, Bao Niu niuba...@gmail.com wrote:
  Hi Mike,
  Thanks for your reply. In my case, the full_name attribute is a hybrid
  property using query on firstName and lastName. When I construct a Person
  instance, I need a session to query the names and build the full_name
  attribute on the fly. So do you think I should remove this session
  immediately after I have built full_name attribute? What if later on my
  application changes this person's firstName? If the session is still
 alive
  it will expire full_name attribute automatically, but if the session was
  removed, there won't be any automatic update on those hybrid_property,
  right?
 
  Doesn't this scenario justify a background thread?
 
 
  On Sat, Jun 28, 2014 at 7:14 AM, Mike Bayer mike...@zzzcomputing.com
  wrote:
 
 
  On 6/28/14, 7:13 AM, Bao Niu wrote:
 
  My situation is like this:
 
  I am developing a web application, which has a Person class, which has
  FirstName and LastName attributes. Now I want to build their full name
  attribute and make this full_name attribute queriable, by using
  hybrid_property, which entails query and hence session. This session for
  querying hybrid_property has its life cycle as long as that particular
  Person instance is active in memory, as in the running process the names
  might get changed, and need to communicate to the database.
 
  In the mean time, in this application I also need another Session
 instance
  to contain those Person instances themselves, and this Session instance
 has
  a quite different life cycle than the above one. I am using
 cherrypy.request
  to hold a thread-local session for this second purpose.
 
  Now it seems to me that both Session instances are necessary, I can't
 use
  one in place of the other. But because handling two sessions at the same
  time is inherently so confusing sometimes, I wonder if I am in the right
  direction? Is this generally considered bad? If it is, then how to deal
 with
  it? Thanks in advance.
 
 
  If this is a web application, having a session that isn't lifecycled to
 a
  request seems like it runs in some kind of background thread or
 something.
  Otherwise, if its some session that stays open in the cherrypy app
 while the
  app is doing nothing, and is only used by requests (somehow?  session
  shouldn't be accessed by multiple things at once) not serving requests,
  that's bad.   if you're using a Session as some kind offline cache,
 that's
  not what it's for and it won't do a good job of that because it isn't
  threadsafe.
 
  think more in terms of database transactions. I use two sessions all
  the time when I want to separate transactions, a background job is
 working
  in a transaction for several seconds, but a second short transaction is
 used
  to write messages to a log table, so that I can see the log table grow
 from
  the outside while the long transaction keeps going.   But database
  transactions overall should be short, and never dormant waiting for
  something to happen, they should be burning through the work they have
 to do
  as fast as possible and completing.  So should your sessions.
 
  --
  You received this message because you are subscribed to a topic in the
  Google Groups sqlalchemy group.
  To unsubscribe from this topic, visit
  https://groups.google.com/d/topic/sqlalchemy/CVIkd-WQiDM/unsubscribe.
  To unsubscribe from this group

Re: [sqlalchemy] Is it considered bad practice to have more than one session instance simultaneously in a web application?

2014-06-30 Thread Bao Niu
Thanks Simon. I think my train of thought isn't quite clear at this point.
Sorry for this, I appreciate your comment and you are right I think I need
to work on my understanding of two different session concept, it's a bit
complex.
On Jun 30, 2014 4:12 AM, Simon King si...@simonking.org.uk wrote:

 What you are suggesting is definitely not what I think of as the
 traditional pattern for a web application (but I don't know exactly
 what you are trying to do, so perhaps you have good reasons for doing
 things this way).

 In the web applications that I write, there is no real state on the
 server in between requests, except what is stored in the database. So
 when a web request comes in, a new sqlalchemy session is created, the
 data is loaded from the database, any necessary changes are made, the
 data is flushed back to the database, and the session is closed. There
 is never any need for data to be held in memory on the server between
 web requests.

 From what you've written, it sounds like you might perhaps be
 confusing the concept of web sessions with database sessions. web
 sessions are a mechanism for identifying a single user, and the
 actions they are performing, across multiple web requests. They are
 typically implemented using cookies, where the cookie can either
 contain the session data itself, or it can contain a key to a set of
 data in the database. However, they have nothing to do with SQLAlchemy
 sessions.

 (I'm also a bit confused by your mention of hybrid_property. As far as
 I'm concerned, hybrid_property is just a convenient mechanism to help
 you avoid writing self.FirstName + ' ' + self.LastName everywhere,
 even in queries)

 Simon


 On Mon, Jun 30, 2014 at 11:28 AM, Bao Niu niuba...@gmail.com wrote:
  Hi Simon,
  Sorry for the poor explanation in my previous post.
  Let me try to clarify this using a flow here:
 
 ---
  1st_web_request comes in to tell the server which person instances are
 to be
  interested. because it involves hybrid_property, and query, so it needs a
  session here, let's call it session_#1;
  ==
  entering a stage where session_#1 has to be active, or otherwise we will
  lose sync ability to update those hybrid_property. At this stage
 session_#1
  basically is just holding a bunch of queried associations of Person
  instances and their names, and standing by, waiting for any update of
  FirstName or LastName to construct a new hybrid_property of Full_Name on
 the
  fly.
  ==
  Now we have 2nd_web_request coming in, which carries a thread-local
 session
  object of its own, let's call it collectively session_#2.(by the way I'm
  using cherrypy and built a plugin and tool to automatically bind a
 session
  for each request) I plan to use this second session object(s) to hold a
  bunch of Person(not just their names, in comparison to session_#2).
 
  My design breaks down here, as I really am lost in how I can deal with
 two
  differently cycled session objects. Or maybe this design itself is
 flawed?
  Maybe I there is something I missed about session as a whole?
 
 
  On Mon, Jun 30, 2014 at 2:57 AM, Simon King si...@simonking.org.uk
 wrote:
 
  I'm not sure I understand your application. Are you saying that you
  have Person instances that stay in memory for longer than a single web
  request?
 
  Simon
 
  On Sun, Jun 29, 2014 at 11:54 AM, Bao Niu niuba...@gmail.com wrote:
   Hi Mike,
   Thanks for your reply. In my case, the full_name attribute is a hybrid
   property using query on firstName and lastName. When I construct a
   Person
   instance, I need a session to query the names and build the full_name
   attribute on the fly. So do you think I should remove this session
   immediately after I have built full_name attribute? What if later on
 my
   application changes this person's firstName? If the session is still
   alive
   it will expire full_name attribute automatically, but if the session
 was
   removed, there won't be any automatic update on those hybrid_property,
   right?
  
   Doesn't this scenario justify a background thread?
  
  
   On Sat, Jun 28, 2014 at 7:14 AM, Mike Bayer mike...@zzzcomputing.com
 
   wrote:
  
  
   On 6/28/14, 7:13 AM, Bao Niu wrote:
  
   My situation is like this:
  
   I am developing a web application, which has a Person class, which
 has
   FirstName and LastName attributes. Now I want to build their full
 name
   attribute and make this full_name attribute queriable, by using
   hybrid_property, which entails query and hence session. This session
   for
   querying hybrid_property has its life cycle as long as that
 particular
   Person instance is active in memory, as in the running process the
   names
   might get changed, and need to communicate to the database.
  
   In the mean time, in this application I also need another Session
   instance
   to contain those Person instances themselves, and this Session
 instance
   has

Re: [sqlalchemy] Is it considered bad practice to have more than one session instance simultaneously in a web application?

2014-06-29 Thread Bao Niu
Hi Mike,
Thanks for your reply. In my case, the full_name attribute is a hybrid
property using query on firstName and lastName. When I construct a Person
instance, I need a session to query the names and build the full_name
attribute on the fly. So do you think I should remove this session
immediately after I have built full_name attribute? What if later on my
application changes this person's firstName? If the session is still alive
it will expire full_name attribute automatically, but if the session was
removed, there won't be any automatic update on those hybrid_property,
right?

Doesn't this scenario justify a background thread?


On Sat, Jun 28, 2014 at 7:14 AM, Mike Bayer mike...@zzzcomputing.com
wrote:


 On 6/28/14, 7:13 AM, Bao Niu wrote:

 My situation is like this:

 I am developing a web application, which has a Person class, which has
 *FirstName* and *LastName* attributes. Now I want to build their full
 name attribute and make this *full_name* attribute queriable, by using
 hybrid_property, which entails query and hence session. This session for
 querying hybrid_property has its life cycle as long as that particular
 Person instance is active in memory, as in the running process the names
 might get changed, and need to communicate to the database.

 In the mean time, in this application I also need another Session instance
 to contain those Person instances themselves, and this Session instance has
 a quite different life cycle than the above one. I am using
 cherrypy.request to hold a thread-local session for this second purpose.

 Now it seems to me that both Session instances are necessary, I can't use
 one in place of the other. But because handling two sessions at the same
 time is inherently so confusing sometimes, I wonder if I am in the right
 direction? Is this generally considered bad? If it is, then how to deal
 with it? Thanks in advance.


 If this is a web application, having a session that isn't lifecycled to a
 request seems like it runs in some kind of background thread or
 something.Otherwise, if its some session that stays open in the
 cherrypy app while the app is doing nothing, and is only used by requests
 (somehow?  session shouldn't be accessed by multiple things at once) not
 serving requests, that's bad.   if you're using a Session as some kind
 offline cache, that's not what it's for and it won't do a good job of that
 because it isn't threadsafe.

 think more in terms of database transactions. I use two sessions all
 the time when I want to separate transactions, a background job is working
 in a transaction for several seconds, but a second short transaction is
 used to write messages to a log table, so that I can see the log table grow
 from the outside while the long transaction keeps going.   But database
 transactions overall should be short, and never dormant waiting for
 something to happen, they should be burning through the work they have to
 do as fast as possible and completing.  So should your sessions.

  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/CVIkd-WQiDM/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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 considered bad practice to have more than one session instance simultaneously in a web application?

2014-06-28 Thread Bao Niu
My situation is like this:

I am developing a web application, which has a Person class, which has 
*FirstName* and *LastName* attributes. Now I want to build their full name 
attribute and make this *full_name* attribute queriable, by using 
hybrid_property, which entails query and hence session. This session for 
querying hybrid_property has its life cycle as long as that particular 
Person instance is active in memory, as in the running process the names 
might get changed, and need to communicate to the database.
 
In the mean time, in this application I also need another Session instance 
to contain those Person instances themselves, and this Session instance has 
a quite different life cycle than the above one. I am using 
cherrypy.request to hold a thread-local session for this second purpose. 

Now it seems to me that both Session instances are necessary, I can't use 
one in place of the other. But because handling two sessions at the same 
time is inherently so confusing sometimes, I wonder if I am in the right 
direction? Is this generally considered bad? If it is, then how to deal 
with it? Thanks in advance.

-- 
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 using column_property preferred over hybrid property in some circumstances?

2014-06-21 Thread Bao Niu
The documentation regarding column_property and hybrid property says both 
methods are intended for linking a sql expression to an attribute, which is 
highly useful. But it is not obvious to junior users which one is 
preferred. Generally speaking under what circumstances I should use one or 
the other? I have read this part several times but still haven't understood 
the overall differences between the two.

I started by reading the ORM tutorial. The tutorial often references links 
to other pages, which makes it impossible for a newbie to learn something 
just by reading the tutorial itself. Sometimes I feel overwhelmed by the 
links to pages that is so technically detailed that after reading it I 
forgot where I left off in the tutorial. By the way, in my opinion a primer 
for newbie users on such advanced features is in high demand.

-- 
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 using column_property preferred over hybrid property in some circumstances?

2014-06-21 Thread Bao Niu
Agreed, very funny comment Mike, and a good one:) Thanks.


On Sat, Jun 21, 2014 at 2:52 PM, Mike Bayer mike...@zzzcomputing.com
wrote:


 On 6/21/14, 4:00 PM, Bao Niu wrote:
  The documentation regarding column_property and hybrid property says
  both methods are intended for linking a sql expression to an
  attribute, which is highly useful. But it is not obvious to junior
  users which one is preferred.
 Heh.Well, one is much older than the other, and truthfully it is
 also not obvious to *me* which one is preferred :).Hybrid property
 is useful for more complex expressions where you'd like to have access
 to an in-Python version when you already have an object loaded.

 The way I used hybrids to a great extent, where i would not have used a
 column_property(), was on an object that has dozens of methods used in a
 complex report, and many of the methods built on each other (this is a
 mock version of that):

 class MyReportThing(Base):
 # ...

@hybrid_property
def x(self):
  # ...

@hybrid_property
def y(self):
  # ...

@hybrid_property
def x_y_variance(self):
return variance(self.x, self.y, ...)

@hybrid_property
def average_foo_x(self):
   # ..

   # many more @hybrid_property objects


 So when we'd generate a full report, we'd load all the MyReportThing
 objects in fully.  The table had perhaps 20 columns.  But the report had
 about 100.  This is because from those 20 columns, the hybrids produced
 80 other variants of the data within.This processing was much better
 accomplished in Python than on the relational database side;  we only
 had to load 20 columns in and then use those 20 cols to generate many
 other answers about that data.   if it was all on the DB side there
 would have been an enormous SQL statement with 100 columns.

 But we still wanted to make these hybrids, because in some cases the
 functions we had on MyReportThing were also useful in a query now and
 then to use in query.filter(), like
 query.filter(MyReportThing.average_foo_x  25).  In fact most of the
 hybrids were part of an abstract interface that applied to many types of
 objects, not just MyReportThing, and in this way the hybrids were very
 flexible in-Python and sometimes in-SQL methods that didn't otherwise
 have any complex interactions within the mapping process.Some
 classes would override some of the hybrids to do something differently,
 and some of them would even present in-Python only for some of them;
 the @expression form would be overridden to raise a NotImplementedError
 for some objects where calculating the values relied on things that
 couldn't be acquired in a simple SQL expression.

 I think for general use, business-level methods, hybrids are a lot more
 flexible and work very well with heavily object oriented techniques.
 The column_property() on the other hand is more about data that you'd
 like to load every time on your object.   When there's some view of data
 that you really want at the SQL level, every time and up front when you
 query(), column_property() can work better for that.But with
 column_property() you really can't fall back onto any kind of
 Python-side replacement of the feature.  It's more rigidly tied to the
 structure of how the database is queried.

 column_property() is also used for rudimental mapping tasks, like if two
 columns in a table or a JOIN should have the same value.

  I started by reading the ORM tutorial. The tutorial often references
  links to other pages, which makes it impossible for a newbie to learn
  something just by reading the tutorial itself.
 well the tutorial is supposed to give you the general idea of how to
 interact between a set of database tables and objects using SQLAlchemy.
 However, it isn't by itself going to teach you much about object
 oriented programming or about relational database programming
 techniques.  I'm not sure of your background, but if it is the case that
 you're learning a little bit about all three at the same time, that is a
 much harder hill to climb.   I think this is somewhat the case for most
 people that I interact with and is entirely normal - for example, I'm
 now learning lots about Openstack, but as it turns out, in order to use
 Openstack I really have to learn a whole lot more about networking as
 well, and this is hard.  But I can't blame Openstack's docs for the fact
 that I'm not super clear on routers/subnetworks/etc. and all that,
 there's multiple concepts to learn at once.I watch very closely what
 people say about SQLAlchemy and at the same time I try to get indicators
 for where they are coming from; the people that really love SQLAlchemy
 the most are those who already have a database background and are also
 not hostile to object oriented programming.  The people who are the most
 grumpy seem to be those who are learning database programming from the
 ground up at the same time.   The product by itself, and its

[sqlalchemy] How to do a query on a returned object?

2014-06-18 Thread Bao Niu
I have a Person class and a Names class, which have a one-to-many 
relationship ( a person can have many names ).

After doing a query like this:

 p = session.query(Person).filter(Person.birthday  1992-01-01).one()


I'd like to further perform a query on the returned object p to select only 
its names that starts with letter B.

Currently I am using a very basic way of looping(by the way I'm using 
automap bases, which is cool!) :

 for n in p.names_collection:
 if n.startswith('B'):
 names.append(n)


I'm wondering if there is some sqlalchemy-specific ways of querying an 
attributes on a returned object? Just need a hint here, I can do the 
research following the lead. Many 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] How to do a query on a returned object?

2014-06-18 Thread Bao Niu
Thank you very much Simon! I skipped those parts without realizing how
useful they are. Thanks a lot for point me the right direction!


On Wed, Jun 18, 2014 at 3:57 AM, Simon King si...@simonking.org.uk wrote:

 On Wed, Jun 18, 2014 at 8:40 AM, Bao Niu niuba...@gmail.com wrote:
  I have a Person class and a Names class, which have a one-to-many
  relationship ( a person can have many names ).
 
  After doing a query like this:
 
  p = session.query(Person).filter(Person.birthday  1992-01-01).one()
 
 
  I'd like to further perform a query on the returned object p to select
 only
  its names that starts with letter B.
 
  Currently I am using a very basic way of looping(by the way I'm using
  automap bases, which is cool!) :
 
  for n in p.names_collection:
  if n.startswith('B'):
  names.append(n)
 
 
  I'm wondering if there is some sqlalchemy-specific ways of querying an
  attributes on a returned object? Just need a hint here, I can do the
  research following the lead. Many thanks.
 

 There's a couple of ways of doing this, and which you use really
 depends on your use case.

 One option is to explicitly query the Names table, using the
 with_parent method to restrict the results to names belonging to the
 correct person:

 name_query =
 session.query(Names).with_parent(p).filter(Names.name.startswith('B'))


 http://docs.sqlalchemy.org/en/rel_0_9/orm/tutorial.html#common-relationship-operators

 Another is to configure the relationship as dynamic:


 http://docs.sqlalchemy.org/en/rel_0_9/orm/collections.html#dynamic-relationship

 If you do this, Person.names_collection will no longer be a simple
 Python list, but instead a special kind of query that is preconfigured
 to select rows related to the person instance. You would use it like:

 name_query = p.names_collection.filter(Names.name.startswith('B'))

 This usually only makes sense for very large collections, since you
 can't really eager-load a dynamic relationship.

 Hope that helps,

 Simon

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/AyLtTlVfwvs/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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 there a way to get the number of active/closed sessions in a scoped_session object?

2014-05-15 Thread Bao Niu
Hi, I've looked up the scoped_session api documentation, but didn't find a 
method to return the current number of active and/or closed sessions 
residing in a scoped_session object. Is there a simple way to achieve this? 
This is for testing reason.

-- 
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] Best way to set up sqlite_pragma for all applications

2014-05-07 Thread Bao Niu
That helps a lot! Every time it is so enjoyable reading your reply, it's so
clear and cogent. Thank you very much Simon! TWO THUMBS UP!!


On Tue, May 6, 2014 at 3:00 AM, Simon King si...@simonking.org.uk wrote:

 On Tue, May 6, 2014 at 10:14 AM, Bao Niu niuba...@gmail.com wrote:
 
  I am seeking some advice on best practice regarding setting up
 sqlite_pragma
  across applications.
 
  I have the following code which I currently put in each and every module
  across my applications, wherever such module uses SQLAlchemy.
 
  @sqlalchemy.event.listens_for(sqlalchemy.engine.Engine, connect)
  def set_sqlite_pragma(dbapi_connection, connection_record):
  cursor = dbapi_connection.cursor()
  cursor.execute(PRAGMA foreign_keys=ON)
  cursor.close()
 

 In the example above, you are attaching an event listener to the
 Engine *class*, which means it will be called any time any engine in
 your application connects to the database. If you wanted, you could
 restrict it to a single engine by attaching the event to the engine
 instance instead, something like:

 engine = create_engine(dburi)
 @sqlalchemy.event.listens_for(engine, 'connect'):
 def handle_connect(dbapi_connection, connection_record):
 # your code here


 
 
  It does the job, but is there a way to centralize this effort so I can
 have
  this snippet only one place for all modules?
  I'm not sure if simply factoring the above snippet out and making it a
  separate module in itself will do the job, because each module will use
  independent sqlalchemy module, right? So setting ModuleA's sqlite_pragma
  doesn't have any effect on ModuleB's sqlite_pragma. Am I right here?

 I'm not sure I understand what you are saying here. Within a single
 process, the sqlalchemy library will only be loaded once, no matter
 how many different modules import sqlalchemy. By attaching an event
 handler to sqlalchemy.engine.Engine, you are asking for that code to
 run for any engine in that process.

 
  Hopefully some pros can give me some simple but practice advice here.
 Many
  thanks.
 

 There shouldn't be anything wrong with putting that event handler in a
 library module, as long as you are sure to import that module from
 somewhere else in your application.

 People are often (rightfully) bothered by code that has import-time
 side-effects. In this case, simply by importing your library module
 you would be globally altering the sqlite behaviour for your process.
 It might be nicer if your library module looked more like this:


 def _set_sqlite_pragma(dbapi_connection, connection_record):
 cursor = dbapi_connection.cursor()
 cursor.execute(PRAGMA foreign_keys=ON)
 cursor.close()

 def enable_sqlite_foreign_keys():
 sqlalchemy.event.listen(sqlalchemy.engine.Engine, 'connect',
 _set_sqlite_pragma)


 ...and then call the enable_sqlite_foreign_keys function somewhere in
 your application setup code.

 Hope that helps,

 Simon

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/lYzM5RwmGAw/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] Best way to set up sqlite_pragma for all applications

2014-05-06 Thread Bao Niu

I am seeking some advice on best practice regarding setting up 
sqlite_pragma across applications.

I have the following code which I currently put in each and every module 
across my applications, wherever such module uses SQLAlchemy.

 @sqlalchemy.event.listens_for(sqlalchemy.engine.Engine, connect)
 def set_sqlite_pragma(dbapi_connection, connection_record):
 cursor = dbapi_connection.cursor()
 cursor.execute(PRAGMA foreign_keys=ON)
 cursor.close()



It does the job, but is there a way to centralize this effort so I can have 
this snippet only one place for all modules?
I'm not sure if simply factoring the above snippet out and making it a 
separate module in itself will do the job, because each module will use 
independent sqlalchemy module, right? So setting ModuleA's sqlite_pragma 
doesn't have any effect on ModuleB's sqlite_pragma. Am I right here?

Hopefully some pros can give me some simple but practice advice here. Many 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Re: Definition for scalar relationship?

2014-03-26 Thread Bao Niu
Thanks very much.
On Mar 25, 2014 10:31 PM, Jonathan Vanasco jonat...@findmeon.com wrote:

 collection = one to many / many to many.

 scalar relationship = one-to-one or many-to-one relationship.

 when defining a relationship, you pass in 'uselist=False' to create define
 the relationship as scalar

  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/szfGlPNeaDc/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] What is the rationale of having to manually set up a relationship between two tables?

2014-03-25 Thread Bao Niu
It really helps. I've upgraded to 0.9.3 and it's great!
On Mar 25, 2014 3:35 AM, Simon King si...@simonking.org.uk wrote:

 I would say that the extension is intended to replace SqlSoup in the
 future, but may not be ready for that quite yet.

 Simon

 On Tue, Mar 25, 2014 at 12:39 AM, Bao Niu niuba...@gmail.com wrote:
  Compare to SQLsoup, is this extension more recommended?
 
 
  On Mon, Mar 24, 2014 at 3:32 AM, Simon King si...@simonking.org.uk
 wrote:
 
  On Mon, Mar 24, 2014 at 6:48 AM, Bao Niu niuba...@gmail.com wrote:
   Suppose we have two tables in an existing database, user and
   address.
   There is a one-to-many relationships between these two tables with a
   foreign
   key user.id==address_user_id.
   Now we *reflect* this schema directly from the database:
  
   from sqlalchemy.ext.declarative import declarative_base
   Base = declarative_base(E)
  
   Class User(Base):
   __tablename__ = 'user'
   __table_args__ = {'autoload': True}
   addresses = sqlalchemy.orm.relationship(Address,
  backref=user)
  
   Class Address(Base):
   __tablename__ = 'address'
   __table_args__ = {'autoload': True}
  
   To me, it is a mystery why the almighty SA can autoload everything,
 but
   not
   an obvious relationship (in red ink). What benefit is it for the user
 to
   manually define such a simple and unambiguous relationship? Can't it
 be
   automatically done, i.e., leaving out the red part?
   Will this feature likely be included in future versions, say,
 sqlalchemy
   1.0?
  
 
  You might be interested in the experimental automap extension:
 
http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html
 
  Hope that helps,
 
  Simon
 
  --
  You received this message because you are subscribed to a topic in the
  Google Groups sqlalchemy group.
  To unsubscribe from this topic, visit
  https://groups.google.com/d/topic/sqlalchemy/_q1tBBfTh0w/unsubscribe.
  To unsubscribe from this group and all its topics, 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.
 
 
  --
  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.

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/_q1tBBfTh0w/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] Definition for scalar relationship?

2014-03-25 Thread Bao Niu
In the Doc for Automap, the Overriding Naming Schemes part, it 
distinguishes the concept of scalar relationship and collection 
relationship. For collection relationship it is easy to understand and 
think of an example. However, what would a *scalar relationship* look like? 
Can't imagine a use case for this.

An example would be very much appreciated. 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] What is the rationale of having to manually set up a relationship between two tables?

2014-03-24 Thread Bao Niu
Suppose we have two tables in an existing database, user and address. 
There is a one-to-many relationships between these two tables with a 
foreign key user.id==address_user_id.
Now we *reflect* this schema directly from the database:

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base(E)

Class User(Base):
__tablename__ = 'user'
__table_args__ = {'autoload': True}
addresses = sqlalchemy.orm.relationship(Address,  backref=user)

Class Address(Base):
__tablename__ = 'address'
__table_args__ = {'autoload': True}

To me, it is a mystery why the almighty SA can autoload everything, but not 
an obvious relationship (in red ink). What benefit is it for the user to 
manually define such a simple and unambiguous relationship? Can't it be 
automatically done, i.e., leaving out the red part?
Will this feature likely be included in future versions, say, sqlalchemy 
1.0?

-- 
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] What is the rationale of having to manually set up a relationship between two tables?

2014-03-24 Thread Bao Niu
Compare to SQLsoup, is this extension more recommended?


On Mon, Mar 24, 2014 at 3:32 AM, Simon King si...@simonking.org.uk wrote:

 On Mon, Mar 24, 2014 at 6:48 AM, Bao Niu niuba...@gmail.com wrote:
  Suppose we have two tables in an existing database, user and address.
  There is a one-to-many relationships between these two tables with a
 foreign
  key user.id==address_user_id.
  Now we *reflect* this schema directly from the database:
 
  from sqlalchemy.ext.declarative import declarative_base
  Base = declarative_base(E)
 
  Class User(Base):
  __tablename__ = 'user'
  __table_args__ = {'autoload': True}
  addresses = sqlalchemy.orm.relationship(Address,  backref=user)
 
  Class Address(Base):
  __tablename__ = 'address'
  __table_args__ = {'autoload': True}
 
  To me, it is a mystery why the almighty SA can autoload everything, but
 not
  an obvious relationship (in red ink). What benefit is it for the user to
  manually define such a simple and unambiguous relationship? Can't it be
  automatically done, i.e., leaving out the red part?
  Will this feature likely be included in future versions, say, sqlalchemy
  1.0?
 

 You might be interested in the experimental automap extension:

   http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html

 Hope that helps,

 Simon

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/_q1tBBfTh0w/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] What's the typical use of the flag *active_history* for sqlalchemy.orm.column_property?

2014-03-22 Thread Bao Niu
In the documentation for sqlalchemy.orm.column_property, there is a section 
explaining the *active_history* flag. It is very terse. I think it is very 
useful but just cannot think of a scenario where I would ever want to use 
*previous* value when I'm setting a new value. Could someone use plain 
language to explain it a bit more? Thanks.

(I sometimes find reading SA documentations is like reading Bible, you know 
the content is good for you, but you cannot easily figure out how. Group 
study really helps:)

-- 
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] What's the typical use of the flag *active_history* for sqlalchemy.orm.column_property?

2014-03-22 Thread Bao Niu
Hi Michael,
Just a quick line, version table is not something particularly useful for
beginner users, am I right? Thanks.


On Sat, Mar 22, 2014 at 2:52 PM, Michael Bayer mike...@zzzcomputing.comwrote:

 when you're using an event such as before_flush() to check on
 attributes.get_history() so that you can see that a new version needs to
 be inserted into a version table, you need the old value of the attribute
 in order to compare.  see the versioned_history example.


 On Mar 22, 2014, at 4:34 PM, Bao Niu niuba...@gmail.com wrote:

 In the documentation for sqlalchemy.orm.column_property, there is a
 section explaining the *active_history* flag. It is very terse. I think it
 is very useful but just cannot think of a scenario where I would ever want
 to use *previous* value when I'm setting a new value. Could someone use
 plain language to explain it a bit more? Thanks.

 (I sometimes find reading SA documentations is like reading Bible, you
 know the content is good for you, but you cannot easily figure out how.
 Group study really helps:)

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


  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/Yvj8q4fv9oE/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] Does reflection reflects everything in an existing SQLite database?

2014-03-21 Thread Bao Niu
I created a database manually using simple sqlite3 in python. When I load 
tables in that database using SqlAlchemy's reflection mode, i.e. setting 
autoload=True, I know all the columns will be reflected and mapped to the 
corresponding classes. However, I'm NOT so sure if the following details 
will also be reflected automatically:

1) foreign_keys flag
For example, if I already set PRAGMA foreign_keys=ON when I created that 
database, do I still need to set up an event listener to set that flag for 
each session when they connect to the database? Or this will be reflected 
automatically?

2) relationships between two tables
Here I mean if a relationship that is not ambiguous, for example, Users and 
Addresses, do I still need to type in and explicitly define an address 
attribute in Users class? Could this be deduced by SqlAlchemy automatically?
(I tried but failed, but I think this might make sense if SqlAlchemy can do 
this automatically when reflecting)

3) constraints
Currently when I examine the __table__ attribute I simply cannot find any 
constraint listed there. I set several ON DELETE RESTRICT, ON UPDATE 
CASCADEwhen I created this database but they are not visible to me even after 
autoload=True.

I'd really appreciate some insight here.  Thanks in advance.

-- 
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] Does reflection reflects everything in an existing SQLite database?

2014-03-21 Thread Bao Niu
Hi Michael,

Thanks for your explanation. Let me build on your explanation and ask for
some further clarification.
Suppose I have the following snippet:

import sqlalchemy
import sqlalchemy.ext.declarative
import sqlalchemy.orm
import sqlalchemy.engine

@sqlalchemy.event.listens_for(sqlalchemy.engine.Engine, connect)
def set_sqlite_pragma(dbapi_connection, connection_record):
cursor = dbapi_connection.cursor()
cursor.execute(PRAGMA foreign_keys=ON)
cursor.close()

This snippet only serves one purpose, which is setting FOREIGN_KEYS=ON. As
you pointed out in last email, if the database already *knows* this flag's
value when it was created, I don't see any point running the above snippet.
So my assumption is, as long as I set PRAGMA foreign_keys=ON when I created
the database, I don't need to remember to turn it on when I use the
database foreign keys later. Is my understanding correct?


On Fri, Mar 21, 2014 at 7:10 AM, Michael Bayer mike...@zzzcomputing.comwrote:

 when using FK constraints with sqlite, the only impact that PRAGMA
 foreign_keys=ON has is whether or not the foreign keys are enforced when
 INSERT, UPDATE or DELETE statements are received by the sqlite database.
  It has no impact on reflection, SQLite is nice enough to tell us about the
 FOREIGN KEY constraints that are present whether or not this pragma is
 enabled.

 so as far as the behavior of reflection and relationship(), PRAGMA
 foreign_keys has no effect.

 as far as ON DELETE RESTRICT and other directives like that i don't think
 SQLAlchemy's SQLite dialect parses those directives right now.  SQLite
 isn't the kind of database that people usually get too deeply involved with
 constraints and triggers and stuff like that.


 On Mar 21, 2014, at 2:18 AM, Bao Niu niuba...@gmail.com wrote:

 I created a database manually using simple sqlite3 in python. When I load
 tables in that database using SqlAlchemy's reflection mode, i.e. setting
 autoload=True, I know all the columns will be reflected and mapped to the
 corresponding classes. However, I'm NOT so sure if the following details
 will also be reflected automatically:

 1) foreign_keys flag
 For example, if I already set PRAGMA foreign_keys=ON when I created that
 database, do I still need to set up an event listener to set that flag for
 each session when they connect to the database? Or this will be reflected
 automatically?

 2) relationships between two tables
 Here I mean if a relationship that is not ambiguous, for example, Users
 and Addresses, do I still need to type in and explicitly define an address
 attribute in Users class? Could this be deduced by SqlAlchemy automatically?
 (I tried but failed, but I think this might make sense if SqlAlchemy can
 do this automatically when reflecting)

 3) constraints
 Currently when I examine the __table__ attribute I simply cannot find any
 constraint listed there. I set several ON DELETE RESTRICT, ON UPDATE
 CASCADE when I created this database but they are not visible to me even
 after autoload=True.

 I'd really appreciate some insight here.  Thanks in advance.

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


  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/-JDkPBG3QOM/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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 knowing change history necessary to understand ORM, or I can get away without it?

2014-03-17 Thread Bao Niu
I've been reading the documentation on Using the Session -- Merging. The 
concept like *change history*, *history stream* occur several times. I know 
the history attribute is something that belongs to the *Core*. But my 
question is, is this really useful for learning ORM? How much knowledge 
about the Core is optimal for a ORM user who just wants to quickly 
establish an application?

Pardon me if my question may not sound very technical, I'm just trying to 
elicit some guide from experienced users here so newbies like me would have 
a better idea of the route to go, instead of hesitating whether to learn 
the core first or just read orm part would be good. For experienced users 
it may not be a question but for new users learning the entire core is a 
HUGE barrier;) Many many 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Could someone please give an example of this paragraph in the Documentation -- Using the session?

2014-03-16 Thread Bao Niu
Hi Michael,

It really works like magic! I mean the refreshing part. What exactly
happens when refreshing a1.bs? Does it actually replace the old b1 inside
the collection with a newer one? I can't wrap my mind around it. And more
importantly, does it mean I should *refresh* every attributes before close
a session, in order to carry their attribute over to the next session?
What is the reason not making such *refreshing* automatic by default???

Sorry for bringing up another question here.


On Sun, Mar 16, 2014 at 10:58 AM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Mar 15, 2014, at 7:41 PM, Bao Niu niuba...@gmail.com wrote:

 Thanks a lot Michael! Just a trivial question here, I noticed in your
 first reply you used:
  # refresh a1.bs

 Why do we need to refresh it? I tried it in my terminal and it doesn't
 emit any sql. Is this one if those secret techniques that differentiate a
 sqlalchemy ninja and a newbie?;)


 it should emit SQL, because the sess.commit() call above has expired the
 collection.  in my script it fails down on a1.bs.remove() if i don't call
 that first.




 On Mar 15, 2014 8:31 AM, Michael Bayer mike...@zzzcomputing.com wrote:

 you have every reason to be confused by that paragraph, which is using
 way too much terminology to express what's important there.   at some
 point, we had to add a behavior which I thought would be confusing to
 people, so that paragraph tries badly to explain what it is.  I should
 replace it with just a simple sentence and an example.  Here's the example:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

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

 e = create_engine(sqlite://, echo=True)
 Base.metadata.create_all(e)

 sess = Session(e)
 a1 = A()
 b1 = B()

 a1.bs = [b1]

 sess.add(a1)
 sess.commit()

 a1.bs  # refresh a1.bs
 sess.close()  # close out - sess is no longer associated with a1, b1

 # all new session
 sess2 = Session(e)

 a1.bs.remove(b1)

 sess2.add(a1)

 # b1 was removed from a1.bs, but
 # is in sess2 anyway! surprising!
 assert b1 in sess2

 # because we need it for the flush, it's still here:
 from sqlalchemy import inspect
 print inspect(a1).attrs.bs.history.deleted






 On Mar 15, 2014, at 5:26 AM, Bao Niu niuba...@gmail.com wrote:

 I've read this paragraph (
 http://docs.sqlalchemy.org/en/latest/orm/session.html#unitofwork-cascades)
 many many times and still can't think of a practical example of what is
 being discussed.

 save-update cascade also cascades the *pending history* of the target
 attribute, meaning that objects which were removed from a scalar or
 collection attribute whose changes have not yet been flushed are also
 placed into the target session. This is because they may have foreign key
 attributes present which will need to be updated to no longer refer to the
 parent.


 I don't think my English is the main stumbling block here because I
 understand the meaning of each word, but as soon as I'm putting them
 together I'm completely lost. Could someone give a simple example here to
 illustrate the main point in this paragraph please? Highly appreciated.
 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 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 a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/MSiBcFB3cFI/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


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


  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/MSiBcFB3cFI/unsubscribe

Re: [sqlalchemy] Could someone please give an example of this paragraph in the Documentation -- Using the session?

2014-03-16 Thread Bao Niu
Got it! It works, that's the main thing!


On Sun, Mar 16, 2014 at 8:24 PM, Michael Bayer mike...@zzzcomputing.comwrote:


 a1.bs only loads something if there's nothing loaded already, or if the
 value was expired.

 usually, as long as you keep objects associated with a Session, there's no
 need to worry about it as things load as they are needed.  but in that
 specific example, I'm moving an object from one session to another and
 trying to trip a condition that only shows up if the object were modified
 while it's detached.   it isn't a usual thing.



 On Mar 16, 2014, at 10:45 PM, Bao Niu niuba...@gmail.com wrote:

 Hi Michael,

 It really works like magic! I mean the refreshing part. What exactly
 happens when refreshinga1.bs? Does it actually replace the old b1 inside
 the collection with a newer one? I can't wrap my mind around it. And more
 importantly, does it mean I should *refresh* every attributes before close
 a session, in order to carry their attribute over to the next session?
 What is the reason not making such *refreshing* automatic by default???

 Sorry for bringing up another question here.


 On Sun, Mar 16, 2014 at 10:58 AM, Michael Bayer mike...@zzzcomputing.com
  wrote:


 On Mar 15, 2014, at 7:41 PM, Bao Niu niuba...@gmail.com wrote:

 Thanks a lot Michael! Just a trivial question here, I noticed in your
 first reply you used:
  # refresh a1.bs

 Why do we need to refresh it? I tried it in my terminal and it doesn't
 emit any sql. Is this one if those secret techniques that differentiate a
 sqlalchemy ninja and a newbie?;)


 it should emit SQL, because the sess.commit() call above has expired the
 collection.  in my script it fails down on a1.bs.remove() if i don't call
 that first.




 On Mar 15, 2014 8:31 AM, Michael Bayer mike...@zzzcomputing.com
 wrote:

 you have every reason to be confused by that paragraph, which is using
 way too much terminology to express what's important there.   at some
 point, we had to add a behavior which I thought would be confusing to
 people, so that paragraph tries badly to explain what it is.  I should
 replace it with just a simple sentence and an example.  Here's the example:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

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

 e = create_engine(sqlite://, echo=True)
 Base.metadata.create_all(e)

 sess = Session(e)
 a1 = A()
 b1 = B()

 a1.bs = [b1]

 sess.add(a1)
 sess.commit()

 a1.bs  # refresh a1.bs
 sess.close()  # close out - sess is no longer associated with a1, b1

 # all new session
 sess2 = Session(e)

 a1.bs.remove(b1)

 sess2.add(a1)

 # b1 was removed from a1.bs, but
 # is in sess2 anyway! surprising!
 assert b1 in sess2

 # because we need it for the flush, it's still here:
 from sqlalchemy import inspect
 print inspect(a1).attrs.bs.history.deleted






 On Mar 15, 2014, at 5:26 AM, Bao Niu niuba...@gmail.com wrote:

 I've read this paragraph (
 http://docs.sqlalchemy.org/en/latest/orm/session.html#unitofwork-cascades)
 many many times and still can't think of a practical example of what is
 being discussed.

 save-update cascade also cascades the *pending history* of the target
 attribute, meaning that objects which were removed from a scalar or
 collection attribute whose changes have not yet been flushed are also
 placed into the target session. This is because they may have foreign key
 attributes present which will need to be updated to no longer refer to the
 parent.


 I don't think my English is the main stumbling block here because I
 understand the meaning of each word, but as soon as I'm putting them
 together I'm completely lost. Could someone give a simple example here to
 illustrate the main point in this paragraph please? Highly appreciated.
 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 tosqlalchemy+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.



 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/MSiBcFB3cFI/unsubscribe.

 To unsubscribe from this group and all its topics, 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] Could someone please give an example of this paragraph in the Documentation -- Using the session?

2014-03-15 Thread Bao Niu
I've read this paragraph 
(http://docs.sqlalchemy.org/en/latest/orm/session.html#unitofwork-cascades) 
many many times and still can't think of a practical example of what is 
being discussed.

save-update cascade also cascades the *pending history* of the target 
 attribute, meaning that objects which were removed from a scalar or 
 collection attribute whose changes have not yet been flushed are also 
 placed into the target session. This is because they may have foreign key 
 attributes present which will need to be updated to no longer refer to the 
 parent.


I don't think my English is the main stumbling block here because I 
understand the meaning of each word, but as soon as I'm putting them 
together I'm completely lost. Could someone give a simple example here to 
illustrate the main point in this paragraph please? Highly appreciated. 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Could someone please give an example of this paragraph in the Documentation -- Using the session?

2014-03-15 Thread Bao Niu
Thanks a lot Michael! Just a trivial question here, I noticed in your first
reply you used:
 # refresh a1.bs

Why do we need to refresh it? I tried it in my terminal and it doesn't emit
any sql. Is this one if those secret techniques that differentiate a
sqlalchemy ninja and a newbie?;)
On Mar 15, 2014 8:31 AM, Michael Bayer mike...@zzzcomputing.com wrote:

 you have every reason to be confused by that paragraph, which is using way
 too much terminology to express what's important there.   at some point, we
 had to add a behavior which I thought would be confusing to people, so that
 paragraph tries badly to explain what it is.  I should replace it with just
 a simple sentence and an example.  Here's the example:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

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

 e = create_engine(sqlite://, echo=True)
 Base.metadata.create_all(e)

 sess = Session(e)
 a1 = A()
 b1 = B()

 a1.bs = [b1]

 sess.add(a1)
 sess.commit()

 a1.bs  # refresh a1.bs
 sess.close()  # close out - sess is no longer associated with a1, b1

 # all new session
 sess2 = Session(e)

 a1.bs.remove(b1)

 sess2.add(a1)

 # b1 was removed from a1.bs, but
 # is in sess2 anyway! surprising!
 assert b1 in sess2

 # because we need it for the flush, it's still here:
 from sqlalchemy import inspect
 print inspect(a1).attrs.bs.history.deleted






 On Mar 15, 2014, at 5:26 AM, Bao Niu niuba...@gmail.com wrote:

 I've read this paragraph (
 http://docs.sqlalchemy.org/en/latest/orm/session.html#unitofwork-cascades)
 many many times and still can't think of a practical example of what is
 being discussed.

 save-update cascade also cascades the *pending history* of the target
 attribute, meaning that objects which were removed from a scalar or
 collection attribute whose changes have not yet been flushed are also
 placed into the target session. This is because they may have foreign key
 attributes present which will need to be updated to no longer refer to the
 parent.


 I don't think my English is the main stumbling block here because I
 understand the meaning of each word, but as soon as I'm putting them
 together I'm completely lost. Could someone give a simple example here to
 illustrate the main point in this paragraph please? Highly appreciated.
 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 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 a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/MSiBcFB3cFI/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] Re: Best practice for binding the engine

2014-03-13 Thread Bao Niu
Hi Simon,
I've got a follow-up question regarding the best practice. You seem to
favour binding engine/connection to the Session over to the Metadata, if I
understood correctly. However, if my application uses reflection, i.e.,
autoload=True, that would require that the Table being aware of which
database it is referring to. In such circumstance, there seems to be no
other choice but binging the engine/connection to Metadata. Do you see any
potential problem in my scenario?

And, in this scenario can I safely remove any bindings to the Session,
because I can trust the bindings with the Tables?

Many thanks!


On Wed, Mar 12, 2014 at 3:23 AM, Simon King si...@simonking.org.uk wrote:

 The order of resolution is described here:


 http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html#sqlalchemy.orm.session.Session.get_bind

 Binds on the session take priority over binds on metadata (passing an
 engine to declarative_base binds the metadata for that base class).

 As far as best practice goes, I would say that it depends on the kind
 of program you are writing. Tables (and mapped classes and so on) tend
 to be created at module scope. Binding an engine at that point means
 that you need to know the database credentials at the time your module
 is imported. This is often fine for quick scripts, but can become
 annoying when structuring a larger application. For a larger
 application, it is probably better to define the structure of your
 data model separately from an actual connection to the database.

 Binding at the session level gives you more flexibility, as you can
 decide on a per-session basis which engine you want to use (for
 example if you had different engines for read and write access).

 Hope that helps,

 Simon

 On Wed, Mar 12, 2014 at 7:25 AM, Bao Niu niuba...@gmail.com wrote:
  Ok, let me try rephrasing my question.
  Is binding an engine/connection simultaneously to a Session and a Table
  considered bad practice? I've looked up the documentation but not
  sufficiently confident about this. There seems no definite/official
 answer
  to this. Could some experienced users help give a definite clue here?
  Thanks.
 
 
  On Sunday, March 9, 2014 12:08:42 AM UTC-8, Bao Niu wrote:
 
  From reading the documentation I learned that you can either bind an
  engine to a session:
  engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
  Session = sessionmaker(bind=engine)
 
   or to a declarative_base:
  engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
  Sqlalchemy_base = declarative_base(engine)
 
  Is there a best practice like always binding to a session?
  I currently bind the engine to both:
  engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
  Session = sessionmaker(bind=engine)
  Sqlalchemy_base = declarative_base(engine)
  From running my codes I didn't encounter any problem. But I wonder how
  SqlAlchemy resolves the conflict internally if there are two bindings?
 Is
  there some potential problems down the road if I kept using this manner?
  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 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 a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/QpkScWlfWx8/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] Re: Best practice for binding the engine

2014-03-12 Thread Bao Niu
Ok, let me try rephrasing my question.
Is binding an engine/connection simultaneously to a Session and a Table 
considered bad practice? I've looked up the documentation but not 
sufficiently confident about this. There seems no definite/official answer 
to this. Could some experienced users help give a definite clue here? 
Thanks.


On Sunday, March 9, 2014 12:08:42 AM UTC-8, Bao Niu wrote:

 From reading the documentation I learned that you can either bind an 
 engine to a session:
 engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
 Session = sessionmaker(bind=engine)

  or to a declarative_base:
 engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
 Sqlalchemy_base = declarative_base(engine)

 Is there a best practice like always binding to a session?
 I currently bind the engine to both:
 engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
 Session = sessionmaker(bind=engine)
 Sqlalchemy_base = declarative_base(engine)
 From running my codes I didn't encounter any problem. But I wonder how 
 SqlAlchemy resolves the conflict internally if there are two bindings? Is 
 there some potential problems down the road if I kept using this manner? 
 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Re: Best practice for binding the engine

2014-03-12 Thread Bao Niu
Yes it is clearly documented there, I need to refine my reading skills:)
thxs Simon! Your explanation makes it much easier to understand for a
newbie like me.
On Mar 12, 2014 3:24 AM, Simon King si...@simonking.org.uk wrote:

 The order of resolution is described here:


 http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html#sqlalchemy.orm.session.Session.get_bind

 Binds on the session take priority over binds on metadata (passing an
 engine to declarative_base binds the metadata for that base class).

 As far as best practice goes, I would say that it depends on the kind
 of program you are writing. Tables (and mapped classes and so on) tend
 to be created at module scope. Binding an engine at that point means
 that you need to know the database credentials at the time your module
 is imported. This is often fine for quick scripts, but can become
 annoying when structuring a larger application. For a larger
 application, it is probably better to define the structure of your
 data model separately from an actual connection to the database.

 Binding at the session level gives you more flexibility, as you can
 decide on a per-session basis which engine you want to use (for
 example if you had different engines for read and write access).

 Hope that helps,

 Simon

 On Wed, Mar 12, 2014 at 7:25 AM, Bao Niu niuba...@gmail.com wrote:
  Ok, let me try rephrasing my question.
  Is binding an engine/connection simultaneously to a Session and a Table
  considered bad practice? I've looked up the documentation but not
  sufficiently confident about this. There seems no definite/official
 answer
  to this. Could some experienced users help give a definite clue here?
  Thanks.
 
 
  On Sunday, March 9, 2014 12:08:42 AM UTC-8, Bao Niu wrote:
 
  From reading the documentation I learned that you can either bind an
  engine to a session:
  engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
  Session = sessionmaker(bind=engine)
 
   or to a declarative_base:
  engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
  Sqlalchemy_base = declarative_base(engine)
 
  Is there a best practice like always binding to a session?
  I currently bind the engine to both:
  engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
  Session = sessionmaker(bind=engine)
  Sqlalchemy_base = declarative_base(engine)
  From running my codes I didn't encounter any problem. But I wonder how
  SqlAlchemy resolves the conflict internally if there are two bindings?
 Is
  there some potential problems down the road if I kept using this manner?
  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 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 a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/QpkScWlfWx8/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


-- 
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] Best practice for binding the engine

2014-03-09 Thread Bao Niu
From reading the documentation I learned that you can either bind an engine 
to a session:
engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
Session = sessionmaker(bind=engine)

 or to a declarative_base:
engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
Sqlalchemy_base = declarative_base(engine)

Is there a best practice like always binding to a session?
I currently bind the engine to both:
engine = create_engine('sqlite:///{}'.format(dbPath), echo=False)
Session = sessionmaker(bind=engine)
Sqlalchemy_base = declarative_base(engine)
From running my codes I didn't encounter any problem. But I wonder how 
SqlAlchemy resolves the conflict internally if there are two bindings? Is 
there some potential problems down the road if I kept using this manner? 
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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] Does pending equal to session.new + session.dirty?

2014-03-08 Thread Bao Niu
Thanks very much Michael, great job clarifying this for me. I've been
watching the tutorial videos you mentioned too. Really looking forward to
1.0 release!


On Fri, Feb 28, 2014 at 12:21 PM, Michael Bayer mike...@zzzcomputing.comwrote:

 session.merge(p) will add a new object as pending if it does not exist
 in the database yet.  if it does exist, then it will be persistent.
 within merge(), the session will emit an autoflush before it begins, so
 anything that is pending at that point will become persistent.  Within the
 merge itself, autoflush is set to false so that any queries within the
 process won't trigger another autoflush.

 Follow the demonstration below which illustrates this.   Also the talk I
 gave at
 http://techspot.zzzeek.org/2012/11/14/pycon-canada-the-sqlalchemy-session-in-depth/goes
  over this in detail.


 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

 class A(Base):
 __tablename__ = 'a'

 id = Column(Integer, primary_key=True)
 data = Column(String)

 engine = create_engine(sqlite://, echo=True)
 Base.metadata.create_all(engine)

 s = Session(engine)

 a1 = A(id=1, data='a1')
 s.add(a1)
 s.commit()
 s.close()


 s = Session(engine)

 a1_persistent = A(id=1)
 a2_pending = A(id=2)

 # merge persistent.  autoflush, then it loads id=1 and
 # populates.
 a1_persistent_merged = s.merge(a1_persistent)

 # it's marked as dirty because attributes were touched...
 assert a1_persistent_merged in s.dirty

 # but it actually has no net changes, so won't actually be flushed
 assert not s.is_modified(a1_persistent_merged)

 # but it is persistent.
 assert inspect(a1_persistent_merged).persistent


 # merge pending. autoflush, then it attempts to load id=2,
 # doesn't find it, adds object to session.new
 a2_pending_merged = s.merge(a2_pending)

 # inspect reveals a2 is pending
 assert inspect(a2_pending_merged).pending

 # and is in .new
 assert a2_pending_merged in s.new

 # now it's not
 s.flush()
 assert a2_pending_merged not in s.new





 On Feb 28, 2014, at 7:19 AM, Bao Niu niuba...@gmail.com wrote:

 As a follow-up question to my last post, could someone please explain a
 bit why using session.add() would add a new item in session.new while using
 session.merge() would add a new item in session.dirty? Even when the
 merge() actually creates a new instance by querying the database?
 I thought merge() should cause the same effect as add() when it creates a
 new instance in IdentitySet(). Why is there such a difference?


 On Wednesday, February 26, 2014 10:16:26 PM UTC-8, Bao Niu wrote:

 From my study of the documentation, it seems to be the case that the
 state of pending refers to the set of instances that is the sum of both
 session.new and session.dirty. Is this understanding correct?

 In addition, using session.add() will almost always lead to a new item in
 session.new, while using session.merge() will almost always lead to a new
 item in session.dirty. For example, if I have an instance named p.

 If I use session.add(p):
 session.add(p)
 session.new
 IdentitySet(([__main__.P object at 0xb69fbc0c])
 session.dirty
 IdentitySet([])

 If I use session.merge(p):
 session.merge(p)
 session.new
 IdentitySet([])
 session.dirty
 IdentitySet(([__main__.P object at 0xb69fbc0c])


 So, the conclusion is:
 session.add == a new item added to session.new
 session.merge == a new item added to session.dirty
 session.add + session.merge == pending

 Is my conclusion correct?


 --
 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/d/optout.


[sqlalchemy] Re: Does pending equal to session.new + session.dirty?

2014-02-28 Thread Bao Niu
As a follow-up question to my last post, could someone please explain a bit 
why using session.add() would add a new item in session.new while using 
session.merge() would add a new item in session.dirty? Even when the 
merge() actually creates a new instance by querying the database?
I thought merge() should cause the same effect as add() when it creates a 
new instance in IdentitySet(). Why is there such a difference?


On Wednesday, February 26, 2014 10:16:26 PM UTC-8, Bao Niu wrote:

 From my study of the documentation, it seems to be the case that the state 
 of pending refers to the set of instances that is the sum of both 
 session.new and session.dirty. Is this understanding correct?

 In addition, using session.add() will almost always lead to a new item in 
 session.new, while using session.merge() will almost always lead to a new 
 item in session.dirty. For example, if I have an instance named p.

 If I use session.add(p):
 session.add(p)
 session.new
 IdentitySet(([__main__.P object at 0xb69fbc0c])
 session.dirty
 IdentitySet([])

 If I use session.merge(p):
 session.merge(p)
 session.new
 IdentitySet([])
 session.dirty
 IdentitySet(([__main__.P object at 0xb69fbc0c])


 So, the conclusion is: 
 session.add == a new item added to session.new
 session.merge == a new item added to session.dirty
 session.add + session.merge == pending

 Is my conclusion correct?



-- 
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] Re: How is 'all connections returned to the connection pool' implemented?

2014-02-26 Thread Bao Niu
This really helps. Thanks Simon!

On Monday, February 24, 2014 8:52:32 PM UTC-8, Bao Niu wrote:


- All transactions are rolled back and all connections returned to the 
connection pool, unless the Session was bound directly to a Connection, in 
which case the connection is still maintained (but still rolled back).

 I'm using SQLite. In the above paragraph, how is 'all connections 
 returned to the connection pool' implemented? SQLite seems *Not* to 
 support connection pooling.
 In addition, what does 'the Session was bound directly to a Connection' 
 refer to?


 By the way, is there a sub-group for beginner users? I appreciate all the 
 responses from pro users here, it's really super newbie-friendly, but I 
 feel my questions tend to be basic and taking up the fast lane is really 
 not my intention.


-- 
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] Does pending equal to session.new + session.dirty?

2014-02-26 Thread Bao Niu
From my study of the documentation, it seems to be the case that the state 
of pending refers to the set of instances that is the sum of both 
session.new and session.dirty. Is this understanding correct?

In addition, using session.add() will almost always lead to a new item in 
session.new, while using session.merge() will almost always lead to a new 
item in session.dirty. For example, if I have an instance named p.

If I use session.add(p):
session.add(p)
session.new
IdentitySet(([__main__.P object at 0xb69fbc0c])
session.dirty
IdentitySet([])

If I use session.merge(p):
session.merge(p)
session.new
IdentitySet([])
session.dirty
IdentitySet(([__main__.P object at 0xb69fbc0c])


So, the conclusion is: 
session.add == a new item added to session.new
session.merge == a new item added to session.dirty
session.add + session.merge == pending

Is my conclusion correct?

-- 
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] Could anyone please help explain expired object in plain language?

2014-02-24 Thread Bao Niu
Sorry for my slowness, but I still have a minor problem understanding
expired object. Why does it always assume that the database carries the
most recent and desired data so that the instances in memory are marked
expired? Can't an expiration mean the other way around, in which the
objects in memory are recent and the database is marked expired, so that
next attribute access would automatically cause an update on the database
according to the attributes on the objects currently in memory?
On Feb 23, 2014 9:16 AM, Gunnlaugur Thor Briem gunnlau...@gmail.com
wrote:

 It means that an object in memory (or some of its attributes),
 representing an entity in the DB, is no longer considered to reflect the
 state of that entity accurately because the entity may have changed in the
 DB. So next time attributes are read from the object, fresh DB state is
 queried. See
 http://docs.sqlalchemy.org/en/latest/orm/session.html#refreshing-expiringTo 
 clear out the currently loaded state on an instance, the instance or
 its individual attributes can be marked as expired, which results in a
 reload to occur upon next access of any of the instance's attrbutes.

 Gulli



 On Sun, Feb 23, 2014 at 10:00 AM, Bao Niu niuba...@gmail.com wrote:

 I read the documentation several times yet still didn't find an official
 definition for expired object, although it is used quite often. To my
 understanding, it means when you update some attributes on a persistent
 object, so those affected attributes that are still lying in database
 become expired. Is my understanding correct, please? Thanks very much.

 --
 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 a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/tGGrkYX5tlE/unsubscribe.
 To unsubscribe from this group and all its topics, 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.


Re: [sqlalchemy] Could anyone please help explain expired object in plain language?

2014-02-24 Thread Bao Niu
Sqlalchemy is great! The more I explore, the more inner beauty of it I
realize.
On Feb 24, 2014 8:15 AM, Jonathan Vanasco jonat...@findmeon.com wrote:

 To expand and clarify Simon's answer into bulletpoints :

 Expired Object
 * The database Session the object belongs to has been closed ( or
 committed unless you tweaked the config )
 * SqlAlchemy considers it 'expired' because it is not reasonable to expect
 the object to reflect the current state of the database
 * the object must be reloaded from the db or 'merged' into a new session.

 Dirty Object
 * There have been changes to attributes on a Clean object loaded from
 the database
 * Changing an attribute , or adding an object, doesn't automatically write
 to the database.
 * You must explicitly call `flush()` to write the database, or `commit()`
 to both write to the database and commit the transaction.

 Overall
 * SqlAlchemy is your friend and looks out for you, avoiding common
 mistakes:
 * It automatically reloads most Expired Objects from the database (and
 raises an error at other times) so you have the most correct data in the ORM
 * It makes you explicitly write to the database when you have new objects
 or changes to commit.

 While it could be possible to extend SqlAlchemy to automatically 'write'
 to the database when you change an attribute, that would cause a lot of SQL
 overhead and probably screw up constraint checks.






  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/tGGrkYX5tlE/unsubscribe.
 To unsubscribe from this group and all its topics, 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] How is 'all connections returned to the connection pool' implemented?

2014-02-24 Thread Bao Niu

   
   - All transactions are rolled back and all connections returned to the 
   connection pool, unless the Session was bound directly to a Connection, in 
   which case the connection is still maintained (but still rolled back).

I'm using SQLite. In the above paragraph, how is 'all connections returned 
to the connection pool' implemented? SQLite seems *Not* to support 
connection pooling.
In addition, what does 'the Session was bound directly to a Connection' 
refer to?


By the way, is there a sub-group for beginner users? I appreciate all the 
responses from pro users here, it's really super newbie-friendly, but I 
feel my questions tend to be basic and taking up the fast lane is really 
not my intention.

-- 
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] Could anyone please help explain expired object in plain language?

2014-02-23 Thread Bao Niu
I read the documentation several times yet still didn't find an official 
definition for expired object, although it is used quite often. To my 
understanding, it means when you update some attributes on a persistent 
object, so those affected attributes that are still lying in database 
become expired. Is my understanding correct, please? Thanks very much.

-- 
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 there a way to examine how many objects a session currently contains?

2014-02-19 Thread Bao Niu
I've looked through the documentation on session, however I didn't seem to 
be able to locate a method that allows me to list all the objects a session 
currently is holding. Could someone point out a tip? Many 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] So session.merge() does not automatically do .add()?

2014-02-19 Thread Bao Niu
I thought I understood the behaviour of session.merge() from reading the 
documentation, but I'm wrong. Here is an example. I have codes below,

class User(Base):
 __tablename__ = 'user'
 id = Column(Integer, primary_key=True)
 name = Column(String(50), nullable=False)
 addresses = relationship(Address, backref=user)

This class has a corresponding table 'user' which has already been 
populated with one row, with its primary key equal to 1.
Now I run the following instructions from python -i:

  u = User(id=1)
  session.merge(u)
  session.commit()

I expected that there should be a sqlalchemy.orm.exc.FlushError, because 
both object u (which has been merged) and the row which has been already in 
the table have their primary key equal to 1. However, nothing happened. 
Sqlalchemy just ignored that merged u!
If I do these instructions:

  session.add(u)
  session.commit()

Then I got a sqlalchemy.orm.exc.FlushError, which was expected.

So, session.merge() does not include .add()? From the documentation it 
seems that it does.

-- 
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] So session.merge() does not automatically do .add()?

2014-02-19 Thread Bao Niu
Thanks for replying. Isn't it the case when I just provide a primary key
for the source object, the attribute shoul be marked expired on the target
instance? In my example I only give the object u a primary key value, so
the newly created object should be an object that only has a primary key
value and wipe out other attributes originally for that row in the table.
However the result is that row stays unchanged after all my instructions.
Is there something I missed here?
On Feb 19, 2014 6:47 AM, Michael Bayer mike...@zzzcomputing.com wrote:


 On Feb 19, 2014, at 6:08 AM, Bao Niu niuba...@gmail.com wrote:

 I thought I understood the behaviour of session.merge() from reading the
 documentation, but I'm wrong. Here is an example. I have codes below,

 class User(Base):
 __tablename__ = 'user'
 id = Column(Integer, primary_key=True)
 name = Column(String(50), nullable=False)
 addresses = relationship(Address, backref=user)

 This class has a corresponding table 'user' which has already been
 populated with one row, with its primary key equal to 1.
 Now I run the following instructions from python -i:

  u = User(id=1)
  session.merge(u)
  session.commit()

 I expected that there should be a sqlalchemy.orm.exc.FlushError, because
 both object u (which has been merged) and the row which has been already in
 the table have their primary key equal to 1. However, nothing happened.
 Sqlalchemy just ignored that merged u!
 If I do these instructions:

  session.add(u)
  session.commit()

 Then I got a sqlalchemy.orm.exc.FlushError, which was expected.

 So, session.merge() does not include .add()? From the documentation it
 seems that it does.


 So first is that the object you pass to merge() is *never* itself added to
 the session.  The object you pass in is unmodified.   The return value of
 merge() is the object that is actually in the Session.  This object will
 either have been newly created, in which case it was added using add(), or
 it was loaded from the database.  But that object is never the one you
 passed in.

 So in your test if primary key 1 already exists, then merge() returned
 the User object it had for that primary key.


-- 
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] So session.merge() does not automatically do .add()?

2014-02-19 Thread Bao Niu
Please allow me to clarify here. So if attributes on source object u are
different from attributes loaded from database, database will always
prevail? I thought the source object u should represent newer version of
the data, shouldn't it?


On Wed, Feb 19, 2014 at 7:21 AM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Feb 19, 2014, at 10:01 AM, Bao Niu niuba...@gmail.com wrote:

 Thanks for replying. Isn't it the case when I just provide a primary key
 for the source object, the attribute shoul be marked expired on the target
 instance?


 no because the target instance a product of either a. essentially loaded
 by session.query(User).get(1), so not expired or b. primary key identity 1
 doesn't exist in the database yet in which case the new object is only
 pending.


-- 
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] What is scalar-holding attribute?

2014-02-10 Thread Bao Niu
Could someone help give a simple definition of scalar-holding attribute? In
documentation for many to one relationship this term occurred, I tried
Google the term but didn't find a definition. Thx.

-- 
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] What is the point to re-define each and every column in __init__ in a class?

2014-02-09 Thread Bao Niu
I'm new to sqlalchemy. I tried to search this question but didn't come up 
with accurate search terms. So I come here for some help from real people 
instead of search engine. For the following code:

 class Places(Base):

 

 __tablename__ = 'moz_places'

  

 id = Column(Integer, primary_key=True)

 url = Column(String)

 title = Column(String)

 rev_host = Column(String)

 visit_count = Column(Integer)

 hidden = Column(Integer)

 typed = Column(Integer)

  

 #--

 def __init__(self, id, url, title, rev_host, visit_count,

  hidden, typed):

 

 self.id = id

 self.url = url

 self.title = title

 self.rev_host = rev_host

 self.visit_count = visit_count

 self.hidden = hidden

 self.typed = typed


If I already defined each column names as class variable,  why do I still 
need to re-define each of them as instance variables? I just can't 
understand the reason. Any hint would be highly appreciated. 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 http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.